home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume25 / trn / part03 < prev    next >
Encoding:
Internet Message Format  |  1991-12-02  |  86.2 KB

  1. Subject:  v25i006:  trn 2.0 - threaded newsreader based on rn 4.4, Part03/13
  2. Newsgroups: comp.sources.unix
  3. Approved: vixie@pa.dec.com
  4.  
  5. Submitted-by: davison@borland.com (Wayne Davison)
  6. Posting-number: Volume 25, Issue 6
  7. Archive-name: trn/part03
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line, then unpack
  11. # it by saving it into a file and typing "sh file".  To overwrite existing
  12. # files, type "sh file -c".  You can also feed this as standard input via
  13. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  14. # will see the following message at the end:
  15. #        "End of archive 3 (of 13)."
  16. # Contents:  Makefile.SH Rnmail.SH addng.c artsrch.c config.h.SH
  17. #   final.c head.c init.c kfile.c ngdata.c tmpthread.c
  18. # Wrapped by vixie@cognition.pa.dec.com on Tue Dec  3 16:34:51 1991
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'Makefile.SH' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'Makefile.SH'\"
  22. else
  23. echo shar: Extracting \"'Makefile.SH'\" \(6864 characters\)
  24. sed "s/^X//" >'Makefile.SH' <<'END_OF_FILE'
  25. case $CONFIG in
  26. X    '') . ./config.sh ;;
  27. esac
  28. echo "Extracting Makefile (with variable substitutions)"
  29. X$cat >Makefile <<!GROK!THIS!
  30. X# $Id: Makefile.SH,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  31. X#
  32. X# This software is Copyright 1991 by Stan Barber. 
  33. X#
  34. X# Permission is hereby granted to copy, reproduce, redistribute or otherwise
  35. X# use this software as long as: there is no monetary profit gained
  36. X# specifically from the use or reproduction of this software, it is not
  37. X# sold, rented, traded or otherwise marketed, and this copyright notice is
  38. X# included prominently in any copy made. 
  39. X#
  40. X# The author make no claims as to the fitness or correctness of this software
  41. X# for any use whatsoever, and it is provided as is. Any use of this software
  42. X# is at the user's own risk. 
  43. X#
  44. X# $Log: Makefile.SH,v $
  45. X# Revision 4.4.2.1  1991/12/01  18:05:42  sob
  46. X# Changed clientlib to be built in the rn tree instead of the nntp tree.
  47. X#
  48. X# Revision 4.4.1.1  1991/09/25  19:38:08  sob
  49. X# Changed some install directives
  50. X#
  51. X# Revision 4.4  1991/09/09  20:18:23  sob
  52. X# release 4.4
  53. X#
  54. X#
  55. X# 
  56. X
  57. CC = $cc
  58. rnbin = $rnbin
  59. rnlib = $rnlib
  60. mansrc = $mansrc
  61. manext = $manext
  62. X#NNTPNNTPDIR = $NNTPSRC
  63. X#NNTPNNTPINC = $rrninclude
  64. CFLAGS = $cflags
  65. LDFLAGS = $posix$iandd
  66. NDIRC = $ndirc
  67. NDIRO = $ndiro
  68. X
  69. libs = $ndirlib $termlib $jobslib $xnxlib $socketlib -lm $sharedclib
  70. mlibs = $ndirlib $jobslib $xnxlib $socketlib $sharedclib
  71. X!GROK!THIS!
  72. X$cat >>Makefile <<'!NO!SUBS!'
  73. X#NNTPnntp=getactive
  74. X#MTmthreading=mthreads mt.check
  75. public = trn tmpthread newsetup newsgroups Pnews Rnmail
  76. private = norm.saver mbox.saver makedir\
  77. X    filexp Pnews.header $(mthreading) $(nntp)
  78. manpages = trn.1 Pnews.1 Rnmail.1 newsetup.1 newsgroups.1
  79. util = Makefile makedepend newsnews
  80. X
  81. X
  82. h1 = addng.h art.h artio.h artsrch.h autosub.h backpage.h bits.h cheat.h 
  83. h2 = common.h decode.h final.h head.h help.h init.h intrp.h kfile.h last.h
  84. h3 = ng.h ngdata.h ngsrch.h ngstuff.h only.h rcln.h rcstuff.h
  85. h4 = respond.h rn.h search.h sw.h term.h util.h
  86. X
  87. h = $(h1) $(h2) $(h3) $(h4)
  88. X
  89. c1 = addng.c art.c artio.c artsrch.c autosub.c backpage.c bits.c cheat.c
  90. c2 = decode.c final.c head.c help.c init.c intrp.c kfile.c last.c $(NDIRC)
  91. c3 = ng.c ngdata.c ngsrch.c ngstuff.c only.c rcln.c rcstuff.c respond.c rn.c
  92. c4 = rthreads.c rt-rn.c rt-select.c search.c sw.c term.c threads.c util.c
  93. c5 = unship.c uudecode.c
  94. X#NNTPc6 = server.c $(NNTPDIR)/common/clientlib.c
  95. X
  96. c = $(c1) $(c2) $(c3) $(c4) $(c5) $(c6)
  97. X
  98. mtc1 = mthreads.c mt-read.c mt-process.c mt-write.c mt-misc.c threads.c $(NDIRC)
  99. X#NNMTmtc2 = $(c6)
  100. mtc = $(mtc1) $(mtc2)
  101. X
  102. tmc = tmpthread.c tm-read.c tm-process.c tm-write.c mt-misc.c threads.c $(mtc2)
  103. X
  104. obj1 = addng.o art.o artio.o artsrch.o autosub.o backpage.o bits.o cheat.o
  105. obj2 = decode.o final.o head.o help.o init.o intrp.o kfile.o last.o $(NDIRO)
  106. obj3 = ng.o ngdata.o ngsrch.o ngstuff.o only.o rcln.o rcstuff.o respond.o rn.o
  107. obj4 = rthreads.o rt-rn.o rt-select.o search.o sw.o term.o threads.o util.o
  108. obj5 = unship.o uudecode.o
  109. X#NNTPobj6 = server.o clientlib.o
  110. X
  111. obj = $(obj1) $(obj2) $(obj3) $(obj4) $(obj5) $(obj6)
  112. X
  113. mto1 = mthreads.o mt-read.o mt-process.o mt-write.o mt-misc.o
  114. mto2 = threads.o getdate.o $(NDIRO)
  115. X#NNMTmto3 = $(obj6)
  116. mtobj = $(mto1) $(mto2) $(mto3)
  117. X
  118. tmo1 = tmpthread.o tm-read.o tm-process.o tm-write.o mt-misc.o
  119. tmo2 = threads.o getdate.o
  120. tmobj = $(tmo1) $(tmo2) $(obj6)
  121. X
  122. lintflags = -phbvxac
  123. X
  124. add1 = Makefile.old Pnews Rnmail mt.check
  125. add2 = bsd config.h config.sh eunice filexp 
  126. add3 = loc makedepend makedir mbox.saver ndir.h newsetup
  127. add4 = newsgroups newsnews norm.saver
  128. add5 = pdp11 usg v7 ultrix sun hp-ux sgi xenix next server.h mips uts
  129. add6 = all pyr grimble .falseactive Pnews.header s5uniq sigtest stardent
  130. X
  131. addedbyconf = $(add1) $(add2) $(add3) $(add4) $(add5) $(add6)
  132. X
  133. X# grrr
  134. SHELL = /bin/sh
  135. X
  136. X
  137. X.c.o:
  138. X    $(CC) -c $(CFLAGS) $*.c
  139. X
  140. all: $(public) $(private) $(util)
  141. X    touch all
  142. X
  143. trn: $(obj)
  144. X    $(CC) $(LDFLAGS) $(obj) $(libs) -o trn
  145. X
  146. mthreads: $(mtobj)
  147. X    $(CC) $(LDFLAGS) $(mtobj) $(mlibs) -o mthreads
  148. X
  149. tmpthread: $(tmobj)
  150. X    $(CC) $(LDFLAGS) $(tmobj) $(mlibs) -o tmpthread
  151. X
  152. mtgroups: mtgroups.o mt-misc.o
  153. X    $(CC) $(LDFLAGS) mtgroups.o mt-misc.o -lcurses $(libs) -o mtgroups
  154. X
  155. X#NNTPgetactive: getactive.o server.o clientlib.o
  156. X#NNTP    $(CC) $(LDFLAGS) getactive.o server.o clientlib.o -o getactive $(libs)
  157. X
  158. X#NNTPclientlib.o:
  159. X#NNTP    $(CC) -c $(CFLAGS) $(NNTPINC) $(NNTPDIR)/common/clientlib.c
  160. X
  161. X# if a .h file depends on another .h file...
  162. X$(h):
  163. X    touch $@
  164. X
  165. install: $(public) $(private) $(manpages)
  166. X# won't work with csh
  167. X    export PATH || exit 1
  168. X    - mv $(rnbin)/trn $(rnbin)/trn.old
  169. X#NNTP    - ln -s trn $(rnbin)/trrn
  170. X    - if test `pwd` != $(rnbin); then cp $(public) $(rnbin); fi
  171. X    - if test `pwd` != $(rnbin); then cd $(rnbin); chmod 755 $(public); strip trn tmpthread ; fi
  172. X    - ./makedir `./filexp $(rnlib)`
  173. X#MT    - cd `./filexp $(rnlib)`; mv mthreads mthreads.old
  174. X    - if test `pwd` != `./filexp $(rnlib)`; then cp INIT $(private) `./filexp $(rnlib)`; fi
  175. X#NNTP    - if test `pwd` != `./filexp $(rnlib)`; then strip `./filexp $(rnlib)`/getactive ; fi
  176. X    - if test ! -f `./filexp $(rnlib)/newsnews`; then cp newsnews `./filexp $(rnlib)`; fi
  177. X    cd `./filexp $(rnlib)`; chmod 755 $(private); chmod 644 INIT newsnews
  178. X#MT    - if test `pwd` != `./filexp $(rnlib)`; then strip `./filexp $(rnlib)`/mthreads ; fi
  179. X    - if test `pwd` != $(mansrc); then \
  180. for page in $(manpages); do \
  181. cp $$page $(mansrc)/`basename $$page .1`.$(manext); \
  182. done; \
  183. X#NNTPecho ".so man$(manext)/trn.$(manext)" > $(mansrc)/trrn.$(manext) ; \
  184. fi
  185. X
  186. clean:
  187. X    rm -f *.o
  188. X
  189. realclean:
  190. X    rm -f trn mthreads tmpthread *.o core $(addedbyconf) 
  191. X#NNTP    rm -f clientlib.o getactive
  192. X
  193. X# The following lint has practically everything turned on.  Unfortunately,
  194. X# you have to wade through a lot of mumbo jumbo that can't be suppressed.
  195. X# If the source file has a /*NOSTRICT*/ somewhere, ignore the lint message
  196. X# for that spot.
  197. X
  198. lint: lint_trn lint_mt lint_tm
  199. X
  200. lint_trn:
  201. X    lint $(lintflags) $(defs) $(c) > trn.fuzz
  202. X
  203. lint_mt:
  204. X    lint $(lintflags) $(mtc) > mt.fuzz
  205. X
  206. lint_tm:
  207. X    lint $(lintflags) $(tmc) > tt.fuzz
  208. X
  209. sabertrn: $(c)
  210. X    #load $(c) $(libs)
  211. X
  212. depend: config.h Makefile
  213. X    ./makedepend
  214. X
  215. X# AUTOMATICALLY GENERATED MAKE DEPENDENCIES--PUT NOTHING BELOW THIS LINE
  216. config.h: config.h.SH config.sh ; sh config.h.SH
  217. Makefile: Makefile.SH config.sh ; sh Makefile.SH
  218. X$(obj):
  219. X    @ echo "You haven't done a "'"make depend" yet!'; exit 1
  220. X!NO!SUBS!
  221. case "$isrrn" in
  222. define) if $test "$serverspool " != " " ; then
  223. X        sed < Makefile -e '/^#NNTP/s/^#NNTP//
  224. X                   /^#MT/s/^#MT//
  225. X                   /^#NNMT/d' > Makefile.new
  226. X    else if $test "$xthread " != "define " ; then
  227. X        sed < Makefile -e '/^#NNTP/s/^#NNTP//
  228. X                   /^#MT/s/^#MT//
  229. X                   /^#NNMT/s/^#NNMT//' > Makefile.new
  230. X    else
  231. X        sed < Makefile -e '/^#NNTP/s/^#NNTP//
  232. X                   /^#MT/d
  233. X                   /^#NNMT/s/^#NNMT//' > Makefile.new
  234. X    fi ; fi
  235. X    ;;
  236. X*)    sed < Makefile -e '/^#NNTP/d
  237. X               /^#MT/s/^#MT//
  238. X               /^#NNMT/d' > Makefile.new
  239. X    ;;
  240. esac
  241. mv Makefile.new Makefile
  242. X$eunicefix Makefile
  243. END_OF_FILE
  244. if test 6864 -ne `wc -c <'Makefile.SH'`; then
  245.     echo shar: \"'Makefile.SH'\" unpacked with wrong size!
  246. fi
  247. # end of 'Makefile.SH'
  248. fi
  249. if test -f 'Rnmail.SH' -a "${1}" != "-c" ; then 
  250.   echo shar: Will not clobber existing file \"'Rnmail.SH'\"
  251. else
  252. echo shar: Extracting \"'Rnmail.SH'\" \(6458 characters\)
  253. sed "s/^X//" >'Rnmail.SH' <<'END_OF_FILE'
  254. case $CONFIG in
  255. X    '') . ./config.sh ;;
  256. esac
  257. echo "Extracting Rnmail (with variable substitutions)"
  258. X$spitshell >Rnmail <<!GROK!THIS!
  259. X$startsh
  260. X# $Id: Rnmail.SH,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  261. X# 
  262. X# $Log: Rnmail.SH,v $
  263. X# Revision 4.4  1991/09/09  20:18:23  sob
  264. X# release 4.4
  265. X#
  266. X#
  267. X# 
  268. X# This software is Copyright 1991 by Stan Barber. 
  269. X#
  270. X# Permission is hereby granted to copy, reproduce, redistribute or otherwise
  271. X# use this software as long as: there is no monetary profit gained
  272. X# specifically from the use or reproduction of this software, it is not
  273. X# sold, rented, traded or otherwise marketed, and this copyright notice is
  274. X# included prominently in any copy made. 
  275. X#
  276. X# The author make no claims as to the fitness or correctness of this software
  277. X# for any use whatsoever, and it is provided as is. Any use of this software
  278. X# is at the user's own risk. 
  279. X#
  280. X#
  281. X# syntax: Rnmail -h headerfile [oldart]        or
  282. X#         Rnmail destination-list         or just
  283. X#         Rnmail
  284. X
  285. export PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
  286. X
  287. X# System dependencies
  288. X
  289. mailer="${mailer-/bin/mail}"
  290. X# if you change this to something that does signatures, take out signature code
  291. X
  292. X# your site name
  293. case $portable in
  294. define)
  295. X    case "$hostcmd" in
  296. X    '') sitename="$sitename" ;;
  297. X    *)  sitename=\`$hostcmd\` ;;
  298. X    esac
  299. X    case \$sitename in
  300. X        *.*)
  301. X            ;;
  302. X        *)
  303. X            sitename=\${sitename}.$domain
  304. X            ;;
  305. X    esac
  306. X    ;;
  307. undef) sitename="$sitename" ;;
  308. esac
  309. X
  310. X# your organization name
  311. orgname="$orgname"
  312. X# what pager you use--if you have kernal paging use cat
  313. pager="\${PAGER-$pager}"
  314. X# how you derive full names, bsd, usg, or other
  315. nametype="$nametype"
  316. X# default editor
  317. defeditor="$defeditor"
  318. X# where the non-publics are
  319. rnlib=$rnlib
  320. X# how not to do a newline with echo
  321. n="$n"
  322. c="$c"
  323. X
  324. test=${test-test}
  325. sed=${sed-sed}
  326. echo=${echo-echo}
  327. cat=${cat-cat}
  328. grep=${grep-grep}
  329. rm=${rm-rm}
  330. X
  331. X!GROK!THIS!
  332. case "$ignoreorg" in
  333. define) $spitshell >>Rnmail <<'!NO!SUBS!'
  334. orgname=${NEWSORG-$orgname}
  335. X!NO!SUBS!
  336. X    ;;
  337. X*)    $spitshell >>Rnmail <<'!NO!SUBS!'
  338. orgname=${NEWSORG-${ORGANIZATION-$orgname}}
  339. X!NO!SUBS!
  340. X    ;;
  341. esac
  342. X$spitshell >>Rnmail <<'!NO!SUBS!'
  343. dotdir=${DOTDIR-${HOME-$LOGDIR}}
  344. tmpart=$dotdir/.letter
  345. X
  346. headerfile=""
  347. case $# in
  348. X0) ;;
  349. X*)  case $1 in
  350. X    -h)
  351. X    headerfile="$2"
  352. X    case $# in
  353. X    3) oldart=$3 ;;
  354. X    esac
  355. X    ;;
  356. X    esac
  357. X    ;;
  358. esac
  359. X
  360. case $headerfile in
  361. X'')
  362. X    case $# in
  363. X    0)
  364. X    to=h
  365. X    while $test "$to" = h ; do
  366. X        $echo ""
  367. X        $echo $n "To: $c"
  368. X        read to
  369. X        case $to in
  370. X        h)
  371. X        $cat <<'EOH'
  372. X
  373. Type the net address of those people that you wish the message sent to.
  374. Additional recipients may be added on the Cc: line when you edit.
  375. X
  376. Separate multiple addresses with spaces.
  377. X
  378. XEOH
  379. X        ;;
  380. X        esac
  381. X    done
  382. X    ;;
  383. X    *)
  384. X    to="$*"
  385. X    ;;
  386. X    esac
  387. X    to=`$echo "$to" | $sed 's/  */ /g'`
  388. X
  389. X    title=h
  390. X    while $test "$title" = h ; do
  391. X    $echo ""
  392. X    $echo $n "Title/Subject: $c"
  393. X    read title
  394. X    case $title in
  395. X    h)
  396. X        $cat <<'EOH'
  397. X
  398. Type the title for your message.  
  399. XEOH
  400. X        ;;
  401. X    esac
  402. X    done
  403. X
  404. X# now build a file with a header for them to edit
  405. X    
  406. X    case $orgname in
  407. X    /*) orgname=`$cat $orgname` ;;
  408. X    esac
  409. X
  410. X    $sed -e '/^Reply-To: $/d' > $tmpart <<EOHeader
  411. To: $to
  412. Subject: $title
  413. Organization: $orgname
  414. Reply-To: $REPLYTO
  415. Cc:
  416. Bcc:
  417. X
  418. XEOHeader
  419. X
  420. X    ;;
  421. X*)
  422. X    $cat < $headerfile  > $tmpart
  423. X    ;;
  424. esac
  425. X
  426. X
  427. file=h
  428. while $test "$file" = h ; do
  429. X    $echo ""
  430. X    $echo $n "Prepared file to include [none]: $c"
  431. X    read file
  432. X    case $file in
  433. X    h)
  434. X    $cat <<'EOH'
  435. X
  436. If you have already produced the body of your message, type the filename
  437. for it here.  If you just want to proceed directly to the editor, type a
  438. RETURN.  In any event, you will be allowed to edit as many times as you
  439. want before you send off the message.
  440. XEOH
  441. X    ;;
  442. X    '')
  443. X    $echo "" >> $tmpart
  444. X    state=edit
  445. X    ;;
  446. X    *)
  447. X    $cat $file >>$tmpart
  448. X    state=ask
  449. X    ;;
  450. X    esac
  451. done
  452. X
  453. X$echo ""
  454. X
  455. while true ; do
  456. X    case $state in
  457. X    edit)
  458. X    rescue="sleep 1; $cat $tmpart >>${HOME-$LOGDIR}/dead.letter ; $echo Message appended to ${HOME-$LOGDIR}/dead.letter ; exit"
  459. X    trap "$rescue" 1
  460. X    trap : 2
  461. X    case "${VISUAL-${EDITOR-}}" in
  462. X    '')
  463. X        tmp=h
  464. X        ;;
  465. X    *)
  466. X        tmp=''
  467. X        ;;
  468. X    esac
  469. X    while $test "$tmp" = h ; do
  470. X        $echo $n "Editor [${VISUAL-${EDITOR-$defeditor}}]: $c"
  471. X        read tmp
  472. X        case $tmp in
  473. X        h)
  474. X        $cat <<'EOH'
  475. X
  476. Type a return to get the default editor, or type the name of the editor you
  477. prefer.  The default editor depends on the VISUAL and EDITOR environment
  478. variables.
  479. X
  480. XEOH
  481. X        ;;
  482. X        '')
  483. X        ;;
  484. X        *)
  485. X        VISUAL=$tmp
  486. X        export VISUAL
  487. X        ;;
  488. X        esac
  489. X    done
  490. X    ${VISUAL-${EDITOR-$defeditor}} $tmpart $oldart
  491. X    trap "$rescue" 2
  492. X    state=ask
  493. X    ;;
  494. X    
  495. X    ask)
  496. X    $echo ""
  497. X    $echo $n "Send, abort, edit, or list? $c"
  498. X    read ans
  499. X    
  500. X    case $ans in
  501. X    a*)
  502. X        state=rescue
  503. X        ;;
  504. X    e*)
  505. X        set $ans
  506. X        case $# in
  507. X        2)  VISUAL="$2" ;;
  508. X        esac
  509. X        state=edit
  510. X        ;;
  511. X    l*)
  512. X        $pager $tmpart
  513. X        state=ask
  514. X        ;;
  515. X    s*)
  516. X        state=send
  517. X        ;;
  518. X    h*)
  519. X        $cat <<'EOH'
  520. X
  521. Type s to send the message, a to abort and append the message to dead.letter,
  522. e to edit the message again, or l to list the message.
  523. X
  524. To invoke an alternate editor, type 'e editor'.
  525. XEOH
  526. X    esac
  527. X    ;;
  528. X    
  529. X    send)
  530. X    if $test -f $dotdir/.signature; then
  531. X        $echo $n "Append .signature file? [y] $c"
  532. X        read ans
  533. X        case $ans in
  534. X        ''|y*)
  535. X        $echo "-- " >> $tmpart
  536. X        cat $dotdir/.signature >> $tmpart
  537. X        ;;
  538. X        esac
  539. X    fi
  540. X    case $mailer in
  541. X    *sendmail)
  542. X        $mailer -t <$tmpart
  543. X        ;;
  544. X# but recmail does not know about Bcc, alas
  545. X    *recmail)
  546. X        $mailer <$tmpart
  547. X        ;;
  548. X    *)
  549. X        set X `$sed <$tmpart -n -e '/^To:/{' -e 's/To: *//p' -e q -e '}'`
  550. X        shift
  551. X        set X "$@" `$sed <$tmpart -n -e '/^Cc:/{' -e 's/Cc: *//p' -e q -e '}'`
  552. X        shift
  553. X        set X "$@" `$sed <$tmpart -n -e '/^Bcc:/{' -e 's/Bcc: *//p' -e q -e '}'`
  554. X        shift
  555. X        $grep -v "^Bcc:"  <$tmpart | $mailer "$@"
  556. X        ;;
  557. X    esac
  558. X    case $? in
  559. X    0)
  560. X        state=cleanup
  561. X        ;;
  562. X    *)
  563. X        state=rescue
  564. X        ;;
  565. X    esac
  566. X    ;;
  567. X    rescue)
  568. X    $cat $tmpart >> ${HOME-$LOGDIR}/dead.letter
  569. X    $echo "Message appended to ${HOME-$LOGDIR}/dead.letter"
  570. X    $echo "A copy may be temporarily found in $tmpart"
  571. X    exit
  572. X    ;;
  573. X    cleanup)
  574. X    case "${MAILRECORD-none}" in
  575. X    none)
  576. X        ;;
  577. X    *)
  578. X        set X ${USER-${LOGNAME-`who am i`}} unknown
  579. X        shift
  580. X        $rnlib/mbox.saver $tmpart "." "." 0 0 Pnews $MAILRECORD "From $1 `date`"
  581. X        if $test $? -eq 0 ; then
  582. X        $echo "Message appended to $MAILRECORD"
  583. X        else
  584. X        $echo "Cannot append to $MAILRECORD"
  585. X        fi
  586. X        ;;
  587. X    esac
  588. X    exit
  589. X    ;;
  590. X    esac
  591. done
  592. X!NO!SUBS!
  593. X$eunicefix Rnmail
  594. chmod 755 Rnmail
  595. END_OF_FILE
  596. if test 6458 -ne `wc -c <'Rnmail.SH'`; then
  597.     echo shar: \"'Rnmail.SH'\" unpacked with wrong size!
  598. fi
  599. # end of 'Rnmail.SH'
  600. fi
  601. if test -f 'addng.c' -a "${1}" != "-c" ; then 
  602.   echo shar: Will not clobber existing file \"'addng.c'\"
  603. else
  604. echo shar: Extracting \"'addng.c'\" \(8453 characters\)
  605. sed "s/^X//" >'addng.c' <<'END_OF_FILE'
  606. X/* $Id: addng.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  607. X *
  608. X * $Log: addng.c,v $
  609. X * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  610. X * Patchlevel 2 changes
  611. X *
  612. X * Revision 4.4  1991/09/09  20:18:23  sob
  613. X * release 4.4
  614. X *
  615. X *
  616. X * 
  617. X */
  618. X/* This software is Copyright 1991 by Stan Barber. 
  619. X *
  620. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  621. X * use this software as long as: there is no monetary profit gained
  622. X * specifically from the use or reproduction of this software, it is not
  623. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  624. X * included prominently in any copy made. 
  625. X *
  626. X * The author make no claims as to the fitness or correctness of this software
  627. X * for any use whatsoever, and it is provided as is. Any use of this software
  628. X * is at the user's own risk. 
  629. X */
  630. X
  631. X#include "EXTERN.h"
  632. X#include "common.h"
  633. X#include "rn.h"
  634. X#include "ngdata.h"
  635. X#include "last.h"
  636. X#include "util.h"
  637. X#include "intrp.h"
  638. X#include "only.h"
  639. X#include "rcstuff.h"
  640. X#ifdef SERVER
  641. X#include "server.h"
  642. X#endif
  643. X#include "final.h"
  644. X#include "INTERN.h"
  645. X#include "addng.h"
  646. X
  647. X#ifdef TZSET
  648. X#include <time.h>
  649. X#else
  650. X#include <sys/time.h>
  651. X#include <sys/timeb.h>
  652. X#endif
  653. X
  654. void
  655. addng_init()
  656. X{
  657. X    ;
  658. X}
  659. X
  660. X#ifdef FINDNEWNG
  661. X/* generate a list of new newsgroups from active file */
  662. X
  663. bool
  664. newlist(munged,checkinlist)
  665. bool_int munged;            /* are we scanning the whole file? */
  666. bool_int checkinlist;
  667. X{
  668. X    char *tmpname;
  669. X    register char *s, *status;
  670. X    register NG_NUM ngnum;
  671. X#ifndef ACTIVE_TIMES
  672. X    long birthof();
  673. X#endif
  674. X
  675. X    tmpname = filexp(RNEWNAME);
  676. X    tmpfp = fopen(tmpname,"w+");
  677. X    if (tmpfp == Nullfp) {
  678. X    printf(cantcreate,tmpname) FLUSH;
  679. X    return FALSE;
  680. X    }
  681. X    UNLINK(tmpname);            /* be nice to the world */
  682. X
  683. X    while (fgets(buf,LBUFLEN,actfp) != Nullch) {
  684. X    /* Check if they want to break out of the new newsgroups search */
  685. X    if (int_count) {
  686. X        int_count = 0;
  687. X        fclose(tmpfp);
  688. X        return FALSE;
  689. X    }
  690. X    if (s = index(buf,' ')) {
  691. X        status=s;
  692. X        while (isdigit(*status) || isspace(*status)) status++;
  693. X        *s++ = '\0';
  694. X        if (strnEQ(buf,"to.",3) || *status == 'x' || *status == '=')
  695. X            /* since = groups are refiling to another group, just
  696. X           ignore their existence */
  697. X        continue;
  698. X#ifdef ACTIVE_TIMES
  699. X        if (inlist(buf) && ((ngnum = find_ng(buf)) == nextrcline
  700. X                || toread[ngnum] == TR_UNSUB)
  701. X#else
  702. X        if (checkinlist ?
  703. X        (inlist(buf) && ((ngnum = find_ng(buf)) == nextrcline
  704. X                 || toread[ngnum] == TR_UNSUB))
  705. X          : (find_ng(buf) == nextrcline
  706. X         && birthof(buf,(ART_NUM)atol(s)) > lasttime)
  707. X#endif
  708. X        ) {
  709. X                    /* if not in .newsrc and younger */
  710. X                    /* than the last time we checked */
  711. X        fprintf(tmpfp,"%s\n",buf);
  712. X                    /* then remember said newsgroup */
  713. X        }
  714. X#ifdef FASTNEW
  715. X        else {            /* not really a new group */
  716. X        if (!munged) {        /* did we assume not munged? */
  717. X            fclose(tmpfp);    /* then go back, knowing that */
  718. X            return TRUE;    /* active file was indeed munged */
  719. X        }
  720. X        }
  721. X#endif
  722. X    }
  723. X#ifdef DEBUGGING
  724. X    else
  725. X        printf("Bad active record: %s\n",buf) FLUSH;
  726. X#endif
  727. X    }
  728. X
  729. X    /* we have successfully generated the list */
  730. X
  731. X    fseek(tmpfp,0L,0);            /* rewind back to the beginning */
  732. X    while (fgets(buf,LBUFLEN,tmpfp) != Nullch) {
  733. X    buf[strlen(buf)-1] = '\0';
  734. X    get_ng(buf,TRUE);        /* add newsgroup, maybe */
  735. X    }
  736. X    fclose(tmpfp);            /* be nice to ourselves */
  737. X    return FALSE;            /* do not call us again */
  738. X}
  739. X
  740. X#ifdef ACTIVE_TIMES
  741. X#ifdef SERVER
  742. X
  743. bool
  744. find_new_groups()
  745. X{
  746. X    char *tmpname;
  747. X    register char *s;
  748. X    struct tm *ts;
  749. X    long now;
  750. X    NG_NUM oldnext = nextrcline;    /* remember # lines in newsrc */
  751. X
  752. X    tmpname = filexp(RNEWNAME);
  753. X    tmpfp = fopen(tmpname,"w+");
  754. X    if (tmpfp == Nullfp) {
  755. X    printf(cantcreate,tmpname) FLUSH;
  756. X    return FALSE;
  757. X    }
  758. X    UNLINK(tmpname);            /* be nice to the world */
  759. X
  760. X    time(&now);
  761. X    ts = gmtime(&lastnewtime);
  762. X    sprintf(ser_line, "NEWGROUPS %02d%02d%02d %02d%02d%02d GMT",
  763. X    ts->tm_year % 100, ts->tm_mon+1, ts->tm_mday,
  764. X    ts->tm_hour, ts->tm_min, ts->tm_sec);
  765. X#ifdef DEBUGGING
  766. X    if (debug & DEB_NNTP)
  767. X    printf(">%s\n", ser_line) FLUSH;
  768. X#endif
  769. X    put_server(ser_line);
  770. X    nntp_get(ser_line, sizeof(ser_line));
  771. X#ifdef DEBUGGING
  772. X    if (debug & DEB_NNTP)
  773. X    printf("<%s\n", ser_line) FLUSH;
  774. X#endif
  775. X    if (*ser_line != CHAR_OK) {        /* and then see if that's ok */
  776. X  error_exit:
  777. X    fclose(tmpfp);
  778. X    printf("Can't get new groups from server:\n%s\n", ser_line);
  779. X    return FALSE;
  780. X    }
  781. X
  782. X    while (1) {
  783. X    if (nntp_get(ser_line, sizeof(ser_line)) < 0)
  784. X        goto error_exit;
  785. X#ifdef DEBUGGING
  786. X    if (debug & DEB_NNTP)
  787. X        printf("<%s\n", ser_line) FLUSH;
  788. X#endif
  789. X    if (ser_line[0] == '.')
  790. X        break;
  791. X    if ((s = index(ser_line, ' ')) != Nullch)
  792. X        *s = '\0';
  793. X    fprintf(tmpfp,"%s\n",ser_line);
  794. X    }
  795. X
  796. X    /* we have successfully generated the list */
  797. X
  798. X    if (ftell(tmpfp)) {
  799. X    fputs("\nFinding new newsgroups:\n",stdout) FLUSH;
  800. X
  801. X    fseek(tmpfp,0L,0);        /* rewind back to the beginning */
  802. X    while (fgets(buf,LBUFLEN,tmpfp) != Nullch) {
  803. X        buf[strlen(buf)-1] = '\0';
  804. X        get_ng(buf,FALSE);        /* add newsgroup, maybe */
  805. X    }
  806. X    lastnewtime = now;        /* remember when we found new groups */
  807. X    }                    /* (ends up back in .rnlast) */
  808. X    fclose(tmpfp);            /* be nice to ourselves */
  809. X
  810. X    return oldnext != nextrcline;
  811. X}
  812. X#else /* not SERVER */
  813. X
  814. bool
  815. find_new_groups()
  816. X{
  817. X    register char *s;
  818. X    long lastone;
  819. X    NG_NUM oldnext = nextrcline;    /* remember # lines in newsrc */
  820. X
  821. X    fstat(fileno(actfp),&filestat);    /* find active file size */
  822. X    lastactsiz = filestat.st_size;    /* just to save it in .rnlast */
  823. X
  824. X    stat(ACTIVE_TIMES,&filestat);    /* did active.times file grow? */
  825. X    if (filestat.st_size == lastnewsize)
  826. X    return FALSE;
  827. X    lastnewsize = filestat.st_size;
  828. X
  829. X    fputs("\nChecking for new newsgroups...\n",stdout) FLUSH;
  830. X
  831. X    s = filexp(ACTIVE_TIMES);
  832. X    tmpfp = fopen(s,"r");
  833. X    if (tmpfp == Nullfp) {
  834. X    printf(cantopen,s) FLUSH;
  835. X    return FALSE;
  836. X    }
  837. X    lastone = time(Null(time_t*)) - 24L * 60 * 60 - 1;
  838. X    while (fgets(buf,LBUFLEN,tmpfp) != Nullch) {
  839. X    if ((s = index(buf, ' ')) != Nullch)
  840. X        if ((lastone = atol(s+1)) >= lastnewtime) {
  841. X        char tmpbuf[80];
  842. X        *s = '\0';
  843. X        if (findact(tmpbuf, buf, s - buf, 0L) >= 0)
  844. X            get_ng(buf,FALSE);    /* add newsgroup, maybe */
  845. X        }
  846. X    }
  847. X    fclose(tmpfp);
  848. X    lastnewtime = lastone+1;        /* remember time of last new group */
  849. X                    /* (ends up back in .rnlast) */
  850. X    return oldnext != nextrcline;
  851. X}
  852. X#endif /* SERVER */
  853. X#else /* not ACTIVE_TIMES */
  854. X
  855. bool
  856. find_new_groups()
  857. X{
  858. X    long oldactsiz = lastactsiz;
  859. X    NG_NUM oldnext = nextrcline;    /* remember # lines in newsrc */
  860. X
  861. X    fstat(fileno(actfp),&filestat);    /* did active file grow? */
  862. X
  863. X    if (filestat.st_size == lastactsiz)
  864. X    return FALSE;
  865. X    lastactsiz = filestat.st_size;    /* remember new size */
  866. X
  867. X#ifdef VERBOSE
  868. X    IF(verbose)
  869. X    fputs("\nChecking active file for new newsgroups...\n",stdout) FLUSH;
  870. X    ELSE
  871. X#endif
  872. X#ifdef TERSE
  873. X    fputs("\nNew newsgroups:\n",stdout) FLUSH;
  874. X#endif
  875. X
  876. X#ifdef FASTNEW                /* bad soft ptrs -> edited active */
  877. X    if (!writesoft && oldactsiz) {    /* maybe just do tail of file? */
  878. X    fseek(actfp,oldactsiz-NL_SIZE,0);
  879. X    fgets(buf,LBUFLEN,actfp);
  880. X    if (*buf == '\n' && !newlist(FALSE,FALSE))
  881. X        goto bugout;
  882. X    }
  883. X#endif
  884. X    fseek(actfp,0L,0);        /* rewind active file */
  885. X    newlist(TRUE,FALSE);        /* sure hope they use hashing... */
  886. bugout:
  887. X    return oldnext != nextrcline;
  888. X}
  889. X
  890. X/* return creation time of newsgroup */
  891. X
  892. long
  893. birthof(ngnam,ngsize)
  894. char *ngnam;
  895. ART_NUM ngsize;
  896. X{
  897. X    char tst[128];
  898. X    long time();
  899. X#ifdef SERVER        /* ngsize not used */
  900. X    int x,tot,min,max;
  901. X    sprintf(tst,"GROUP %s",ngnam);
  902. X#ifdef DEBUGGING
  903. X    if (debug & DEB_NNTP)
  904. X    printf(">%s\n", tst) FLUSH;
  905. X#endif
  906. X    put_server(tst);
  907. X    (void) nntp_get(tst, sizeof(tst));
  908. X#ifdef DEBUGGING
  909. X    if (debug & DEB_NNTP)
  910. X    printf("<%s\n", tst) FLUSH;
  911. X#endif
  912. X    if (*tst != CHAR_OK) return(0); /* not a real group */
  913. X    (void) sscanf(tst,"%d%d%d%d",&x,&tot,&min,&max);
  914. X    if (tot > 0) return(time(Null(long *)));
  915. X    else return(0);
  916. X#else /* not SERVER */
  917. X
  918. X    sprintf(tst, ngsize ? "%s/%s/1" : "%s/%s" ,spool,getngdir(ngnam));
  919. X    if (stat(tst,&filestat) < 0)
  920. X    return (ngsize ? 0L : time(Null(long *)));
  921. X    /* not there, assume something good */
  922. X    else
  923. X    return filestat.st_mtime;
  924. X
  925. X#endif
  926. X}
  927. X#endif /* ACTIVE_TIMES */
  928. X
  929. bool
  930. scanactive()
  931. X{
  932. X    NG_NUM oldnext = nextrcline;    /* remember # lines in newsrc */
  933. X
  934. X    fseek(actfp,0L,0);
  935. X    newlist(TRUE,TRUE);
  936. X    if (nextrcline != oldnext) {    /* did we add any new groups? */
  937. X    return TRUE;
  938. X    }
  939. X    return FALSE;
  940. X}
  941. X
  942. X#endif
  943. X
  944. END_OF_FILE
  945. if test 8453 -ne `wc -c <'addng.c'`; then
  946.     echo shar: \"'addng.c'\" unpacked with wrong size!
  947. fi
  948. # end of 'addng.c'
  949. fi
  950. if test -f 'artsrch.c' -a "${1}" != "-c" ; then 
  951.   echo shar: Will not clobber existing file \"'artsrch.c'\"
  952. else
  953. echo shar: Extracting \"'artsrch.c'\" \(8260 characters\)
  954. sed "s/^X//" >'artsrch.c' <<'END_OF_FILE'
  955. X/* $Id: artsrch.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  956. X *
  957. X * $Log: artsrch.c,v $
  958. X * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  959. X * Patchlevel 2 changes
  960. X *
  961. X * Revision 4.4  1991/09/09  20:18:23  sob
  962. X * release 4.4
  963. X *
  964. X *
  965. X * 
  966. X */
  967. X/* This software is Copyright 1991 by Stan Barber. 
  968. X *
  969. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  970. X * use this software as long as: there is no monetary profit gained
  971. X * specifically from the use or reproduction of this software, it is not
  972. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  973. X * included prominently in any copy made. 
  974. X *
  975. X * The author make no claims as to the fitness or correctness of this software
  976. X * for any use whatsoever, and it is provided as is. Any use of this software
  977. X * is at the user's own risk. 
  978. X */
  979. X
  980. X#include "EXTERN.h"
  981. X#include "common.h"
  982. X#include "search.h"
  983. X#include "term.h"
  984. X#include "util.h"
  985. X#include "intrp.h"
  986. X#include "bits.h"
  987. X#include "kfile.h"
  988. X#include "head.h"
  989. X#include "final.h"
  990. X#include "cheat.h"
  991. X#ifdef SERVER
  992. X#include "server.h"
  993. X#endif
  994. X#include "ng.h"
  995. X#include "artio.h"
  996. X#ifdef USETHREADS
  997. X#include "threads.h"
  998. X#include "rthreads.h"
  999. X#include "ngdata.h"
  1000. X#endif
  1001. X#include "INTERN.h"
  1002. X#include "artsrch.h"
  1003. X
  1004. void
  1005. artsrch_init()
  1006. X{
  1007. X#ifdef ARTSEARCH
  1008. X#ifdef ZEROGLOB
  1009. X    init_compex(&sub_compex);
  1010. X    init_compex(&art_compex);
  1011. X#endif
  1012. X#endif
  1013. X}
  1014. X
  1015. X/* search for an article containing some pattern */
  1016. X
  1017. X#ifdef ARTSEARCH
  1018. int
  1019. art_search(patbuf,patbufsiz,get_cmd)
  1020. char *patbuf;                /* if patbuf != buf, get_cmd must */
  1021. int patbufsiz;
  1022. int get_cmd;                /*   be set to FALSE!!! */
  1023. X{
  1024. X    char *pattern;            /* unparsed pattern */
  1025. X    register char cmdchr = *patbuf;    /* what kind of search? */
  1026. X    register char *s;
  1027. X    bool backward = cmdchr == '?' || cmdchr == Ctl('p');
  1028. X                    /* direction of search */
  1029. X    COMPEX *compex;            /* which compiled expression */
  1030. X    char *cmdlst = Nullch;        /* list of commands to do */
  1031. X    int normal_return = SRCH_NOTFOUND;    /* assume no commands */
  1032. X    bool saltaway = FALSE;        /* store in KILL file? */
  1033. X    char howmuch;            /* search just the subjects */
  1034. X    bool doread;            /* search read articles? */
  1035. X    bool foldcase = TRUE;        /* fold upper and lower case? */
  1036. X
  1037. X    int_count = 0;
  1038. X    if (cmdchr == '/' || cmdchr == '?') {    /* normal search? */
  1039. X    if (get_cmd && buf == patbuf)
  1040. X        if (!finish_command(FALSE))    /* get rest of command */
  1041. X        return SRCH_ABORT;
  1042. X    compex = &art_compex;
  1043. X    if (patbuf[1]) {
  1044. X        howmuch = 0;
  1045. X        doread = FALSE;
  1046. X    }
  1047. X    else {
  1048. X        howmuch = art_howmuch;
  1049. X        doread = art_doread;
  1050. X    }
  1051. X    s = cpytill(buf,patbuf+1,cmdchr);/* ok to cpy buf+1 to buf */
  1052. X    pattern = buf;
  1053. X    if (*pattern) {
  1054. X        if (*lastpat)
  1055. X        free(lastpat);
  1056. X        lastpat = savestr(pattern);
  1057. X    }
  1058. X    if (*s) {            /* modifiers or commands? */
  1059. X        for (s++; *s && index("Kharc",*s); s++) {
  1060. X        if (*s == 'h')        /* scan header */
  1061. X            howmuch = 1;
  1062. X        else if (*s == 'a')    /* scan article */
  1063. X            howmuch = 2;
  1064. X        else if (*s == 'r')    /* scan read articles */
  1065. X            doread = TRUE;
  1066. X        else if (*s == 'K')    /* put into KILL file */
  1067. X            saltaway = TRUE;
  1068. X        else if (*s == 'c')    /* make search case sensitive */
  1069. X            foldcase = FALSE;
  1070. X        }
  1071. X    }
  1072. X    while (isspace(*s) || *s == ':')
  1073. X        s++;
  1074. X    if (*s) {
  1075. X        if (*s == 'm' || *s == 'M')
  1076. X        doread = TRUE;
  1077. X        if (*s == 'k')        /* grandfather clause */
  1078. X        *s = 'j';
  1079. X        cmdlst = savestr(s);
  1080. X        normal_return = SRCH_DONE;
  1081. X    }
  1082. X    art_howmuch = howmuch;
  1083. X    art_doread = doread;
  1084. X    if (srchahead)
  1085. X        srchahead = -1;
  1086. X    }
  1087. X    else {
  1088. X    register char *h;
  1089. X
  1090. X    howmuch = 0;            /* just search subjects */
  1091. X    doread = (cmdchr == Ctl('p'));
  1092. X    if (cmdchr == Ctl('n'))
  1093. X        normal_return = SRCH_SUBJDONE;
  1094. X    compex = &sub_compex;
  1095. X    pattern = patbuf+1;
  1096. X    strcpy(pattern,": *");
  1097. X    h = pattern + strlen(pattern);
  1098. X    interp(h,patbufsiz - (h-patbuf),"%\\s");  /* fetch current subject */
  1099. X    if (cmdchr == 'K') {
  1100. X        saltaway = TRUE;
  1101. X        cmdchr = 'k';
  1102. X    }
  1103. X    if (cmdchr == 'k') {
  1104. X        normal_return = SRCH_DONE;
  1105. X        cmdlst = savestr("j");
  1106. X        mark_as_read();        /* this article has this subject */
  1107. X        if (!*h) {
  1108. X#ifdef VERBOSE
  1109. X        IF(verbose)
  1110. X            fputs("\nCannot delete null subject.\n",stdout) FLUSH;
  1111. X        ELSE
  1112. X#endif
  1113. X#ifdef TERSE
  1114. X            fputs("\nNull subject.\n",stdout) FLUSH;
  1115. X#endif
  1116. X        return SRCH_ABORT;
  1117. X        }
  1118. X#ifdef VERBOSE
  1119. X        else if (verbose)
  1120. X        printf("\nMarking subject \"%s\" as read.\n",h) FLUSH;
  1121. X#endif
  1122. X    }
  1123. X    else if (!srchahead)
  1124. X        srchahead = -1;
  1125. X    {            /* compensate for notesfiles */
  1126. X        register int i;
  1127. X        for (i = 24; *h && i--; h++)
  1128. X        if (*h == '\\')
  1129. X            h++;
  1130. X        *h = '\0';
  1131. X    }
  1132. X#ifdef DEBUGGING
  1133. X    if (debug) {
  1134. X        printf("\npattern = %s\n",pattern) FLUSH;
  1135. X    }
  1136. X#endif
  1137. X    }
  1138. X    if ((s = compile(compex,pattern,TRUE,foldcase)) != Nullch) {
  1139. X                    /* compile regular expression */
  1140. X    printf("\n%s\n",s) FLUSH;
  1141. X    return SRCH_ABORT;
  1142. X    }
  1143. X#ifdef KILLFILES
  1144. X    if (saltaway) {
  1145. X    char saltbuf[LBUFLEN];
  1146. X
  1147. X    s = saltbuf;
  1148. X    sprintf(s,"/%s/",pattern);
  1149. X    s += strlen(s);
  1150. X    if (doread)
  1151. X        *s++ = 'r';
  1152. X    if (howmuch==1)
  1153. X        *s++ = 'h';
  1154. X    else if (howmuch==2)
  1155. X        *s++ = 'a';
  1156. X    *s++ = ':';
  1157. X    if (!cmdlst)
  1158. X        cmdlst = savestr("j");
  1159. X    safecpy(s,cmdlst,LBUFLEN-(s-saltbuf));
  1160. X    kf_append(saltbuf);
  1161. X    }
  1162. X#endif
  1163. X    if (cmdlst && index(cmdlst,'='))
  1164. X    normal_return = SRCH_ERROR;    /* listing subjects is an error? */
  1165. X    if (get_cmd) {
  1166. X    fputs("\nSearching...\n",stdout) FLUSH;
  1167. X                    /* give them something to read */
  1168. X    }
  1169. X#ifdef USETHREADS
  1170. X    if (mode == 't') {
  1171. X    if (!cmdlst)
  1172. X        cmdlst = savestr("+");    /* thread selector's default command */
  1173. X    if (unread_selector)
  1174. X        doread = TRUE;
  1175. X    normal_return = SRCH_DONE;
  1176. X    }
  1177. X#endif
  1178. X    if (backward) {
  1179. X    if (cmdlst && art <= lastart)
  1180. X        art++;            /* include current article */
  1181. X    if (doread)
  1182. X        check_first(absfirst);
  1183. X    }
  1184. X    else {
  1185. X    if (art > lastart) {
  1186. X        art = (doread ? absfirst : firstart);
  1187. X        check_first(art--);
  1188. X    }
  1189. X    else if (cmdlst && art >= absfirst)
  1190. X        art--;            /* include current article */
  1191. X    }
  1192. X    if (srchahead > 0) {
  1193. X    if (!backward)
  1194. X        art = srchahead - 1;
  1195. X    srchahead = -1;
  1196. X    }
  1197. X    assert(!cmdlst || *cmdlst);
  1198. X    perform_cnt = 0;
  1199. X    for (;;) {
  1200. X    if (backward ?
  1201. X        (--art < absfirst || (!doread && art < firstart)) :
  1202. X        (++art > lastart)
  1203. X      ) {            /* out of articles? */
  1204. X        if (cmdlst)
  1205. X        free(cmdlst);
  1206. X        return normal_return;
  1207. X    }
  1208. X    if (int_count) {
  1209. X        int_count = 0;
  1210. X        if (cmdlst)
  1211. X        free(cmdlst);
  1212. X        return SRCH_INTR;
  1213. X    }
  1214. X    /*NOSTRICT*/
  1215. X    if (doread || !was_read(art)) {
  1216. X        if (wanted(compex,art,howmuch)) {
  1217. X                    /* does the shoe fit? */
  1218. X        if (cmdlst) {
  1219. X            if (perform(cmdlst,TRUE)) {
  1220. X            if (cmdlst)
  1221. X                free(cmdlst);
  1222. X            return SRCH_INTR;
  1223. X            }
  1224. X        }
  1225. X        else {
  1226. X            if (cmdlst)
  1227. X            free(cmdlst);
  1228. X            return SRCH_FOUND;
  1229. X        }
  1230. X        }
  1231. X        else if (!cmdlst && ! (art%50)) {
  1232. X        printf("...%ld",(long)art);
  1233. X        fflush(stdout);
  1234. X        }
  1235. X    }
  1236. X    }
  1237. X}
  1238. X
  1239. X/* determine if article fits pattern */
  1240. X/* returns TRUE if it exists and fits pattern, FALSE otherwise */
  1241. X
  1242. bool
  1243. wanted(compex, artnum, scope)
  1244. COMPEX *compex;
  1245. ART_NUM artnum;
  1246. char_int scope;
  1247. X{
  1248. X    if (!scope) {
  1249. X    char subj_buf[266];
  1250. X    
  1251. X#ifdef USETHREADS
  1252. X    if (ThreadedGroup)
  1253. X        find_article(art);
  1254. X    if (p_art) {
  1255. X        if (mode != 't')
  1256. X        strcpy(subj_buf, "Subject: ");
  1257. X        else
  1258. X        *subj_buf = '\0';
  1259. X        if (p_art->subject != -1)
  1260. X        strcat(subj_buf,subject_ptrs[p_art->subject]);
  1261. X    }
  1262. X    else
  1263. X#endif
  1264. X    {
  1265. X        strcpy(subj_buf, "Subject: ");
  1266. X        strncpy(subj_buf+9,fetchsubj(artnum,FALSE,FALSE),256);
  1267. X    }
  1268. X#ifdef DEBUGGING
  1269. X    if (debug & DEB_SEARCH_AHEAD)
  1270. X        printf("%s\n",subj_buf) FLUSH;
  1271. X#endif
  1272. X    return execute(compex,subj_buf) != Nullch;
  1273. X    }
  1274. X#ifdef CACHESUBJ
  1275. X    else
  1276. X    fetchsubj(artnum,FALSE,FALSE);/* might as well get subject handy */
  1277. X#endif
  1278. X    
  1279. X#ifdef SERVER
  1280. X    if (scope == 1){
  1281. X    if (nntpopen(artnum,GET_HEADER) == Nullfp) /* we only need the header */
  1282. X        return FALSE;
  1283. X    }
  1284. X    else
  1285. X#endif
  1286. X    if (artopen(artnum) == Nullfp)    /* ensure that article is open */
  1287. X
  1288. X    return FALSE;            /* if not, return NO MATCH */
  1289. X    scope--;
  1290. X    while (fgets(buf,LBUFLEN,artfp) != Nullch) {
  1291. X                    /* for each line of article */
  1292. X    if (!scope && index(buf,':') == Nullch && *buf != ' ' && *buf != '\t')
  1293. X                    /* if headers only and out of header */
  1294. X        return FALSE;        /* say no go */
  1295. X    if (execute(compex,buf) != Nullch) {
  1296. X                    /* does pattern matcher match? */
  1297. X        return TRUE;        /* say Eureka */
  1298. X    }
  1299. X    }
  1300. X    return FALSE;            /* out of article, so no match */
  1301. X}
  1302. X#endif
  1303. X
  1304. END_OF_FILE
  1305. if test 8260 -ne `wc -c <'artsrch.c'`; then
  1306.     echo shar: \"'artsrch.c'\" unpacked with wrong size!
  1307. fi
  1308. # end of 'artsrch.c'
  1309. fi
  1310. if test -f 'config.h.SH' -a "${1}" != "-c" ; then 
  1311.   echo shar: Will not clobber existing file \"'config.h.SH'\"
  1312. else
  1313. echo shar: Extracting \"'config.h.SH'\" \(6846 characters\)
  1314. sed "s/^X//" >'config.h.SH' <<'END_OF_FILE'
  1315. X: create config.h file
  1316. case $CONFIG in
  1317. X    '') . ./config.sh ;;
  1318. esac
  1319. echo "Extracting config.h (with variable substitutions)"
  1320. case "$threaddir" in
  1321. X'.')    threaddir='/usr/spool/threads'
  1322. X    tdir='undef';;
  1323. X*)    tdir='define';;
  1324. esac
  1325. case "$serverspool" in
  1326. X'') sspool='undef';;
  1327. X*)  sspool='define';;
  1328. esac
  1329. case "$activetimes" in
  1330. X'none')    acttimes='undef';;
  1331. X*)    acttimes='define';;
  1332. esac
  1333. case "$syslog" in
  1334. LOG_*)    syslog2='define';;
  1335. X*)    syslog2='undef';;
  1336. esac
  1337. case "$hostfile" in
  1338. X'')    usehostfile='undef';;
  1339. X*)    usehostfile='define';;
  1340. esac
  1341. X
  1342. X$sed 's,^#undef,/*#undef,' >config.h <<EOT
  1343. X/* config.h
  1344. X * This file was produced by running the config.h.SH script, which
  1345. X * gets its values from config.sh, which is generally produced by
  1346. X * running Configure.
  1347. X *
  1348. X * Feel free to modify any of this as the need arises.  Note, however,
  1349. X * that running config.h.SH again will wipe out any changes you've made.
  1350. X * For a more permanent change edit config.sh and rerun config.h.SH.
  1351. X * $Id: config.h.SH,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  1352. X *
  1353. X * $Log: config.h.SH,v $
  1354. X * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  1355. X * Fixed problems with CTRLA flag.
  1356. X *
  1357. X * Revision 4.4  1991/09/09  20:18:23  sob
  1358. X * release 4.4
  1359. X *
  1360. X *
  1361. X * 
  1362. X */
  1363. X/* This software is Copyright 1991 by Stan Barber. 
  1364. X *
  1365. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  1366. X * use this software as long as: there is no monetary profit gained
  1367. X * specifically from the use or reproduction of this software, it is not
  1368. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  1369. X * included prominently in any copy made. 
  1370. X *
  1371. X * The author make no claims as to the fitness or correctness of this software
  1372. X * for any use whatsoever, and it is provided as is. Any use of this software
  1373. X * is at the user's own risk. 
  1374. X */
  1375. X
  1376. X/* name of the site.  May be overridden by HOSTFILE, gethostname, uname, etc. */
  1377. X#define SITENAME "$sitename"
  1378. X#$usehostfile HOSTFILE "$hostfile"    /* defined if we read the hostname from a file */
  1379. X
  1380. X/* domain name for the site */
  1381. X#define OURDOMAIN "$domain"
  1382. X
  1383. X/* name of the organization, may be a file name */
  1384. X#define ORGNAME "$orgname"
  1385. X
  1386. X/* ignore the ORGANIZATION environment variable */
  1387. X#$ignoreorg IGNOREORG        /**/
  1388. X
  1389. X/* login name of news administrator, if any. */
  1390. X#$isadmin NEWSADMIN "$newsadmin"    /**/
  1391. X
  1392. X/* news library, may use only ~ and %l expansion */
  1393. X#define LIB "$lib"
  1394. X
  1395. X/* rn private library, may use ~ expansion, %x and %l */
  1396. X#define RNLIB "$rnlib"
  1397. X
  1398. X/* mthreads private files */
  1399. X#define MTLIB "$mtlib"
  1400. X
  1401. X/* location of the news spool directory, may use ~ expansion, %x and %l */
  1402. X#define SPOOL "$spool"
  1403. X
  1404. X/* the server's spool directory if generating an NNTP trn & a local mthreads */
  1405. X#$sspool SERVERSPOOL "$serverspool"    /* forces local mthreads */
  1406. X
  1407. X/* put thread files in each spool directory, unless THREAD_DIR is defined */
  1408. X#$tdir THREAD_DIR "$threaddir"    /* base directory */
  1409. X
  1410. X/* save in subdirectories unless LONG_THREAD_NAMES & THREAD_DIR are defined */
  1411. X#undef LONG_THREAD_NAMES        /* not for short-name systems */
  1412. X
  1413. X/* I doubt you'd want to undefine this, but someone may */
  1414. X#define USETMPTHREAD            /* use tmpthread to update threads */
  1415. X
  1416. X/* location of the active file, may use ~ expansion, %x and %l */
  1417. X#define ACTIVE "$active"
  1418. X
  1419. X/* define where the active.times file is kept if we're using it */
  1420. X#$acttimes ACTIVE_TIMES "$activetimes"    /* including name */
  1421. X
  1422. X/* location of spooled mail */
  1423. X#define MAILFILE "$maildir"
  1424. X
  1425. X/* default shell--ok to be a slow shell like csh */
  1426. X#define PREFSHELL "$pref"
  1427. X
  1428. X/* default editor */
  1429. X#define DEFEDITOR "$defeditor"
  1430. X
  1431. X/* root uid */
  1432. X#define ROOTID $rootid
  1433. X
  1434. X/* what is the first character of a mailbox? */
  1435. X#define MBOXCHAR '$mboxchar'
  1436. X
  1437. X/* how to cancel an article */
  1438. X#define CANCEL "$inews -h <%h"
  1439. X
  1440. X/* distribution groups */
  1441. X#define LOCDIST   "$locpref"
  1442. X#define ORGDIST   "$orgpref"
  1443. X#define CITYDIST  "$citypref"
  1444. X#define STATEDIST "$statepref"
  1445. X#define CNTRYDIST "$cntrypref"
  1446. X#define CONTDIST  "$contpref"
  1447. X
  1448. X#define THREAD_INIT $threaddef
  1449. X#define SELECT_INIT $selectdef
  1450. X
  1451. X#$strchr index  strchr        /* cultural */
  1452. X#$strchr rindex strrchr        /*  differences? */
  1453. X#$memcpy bcopy(s,d,n) memcpy((char*)d,(char*)s,(int)n)    /* Different */
  1454. X#$memcpy bzero(d,n)   memset((char*)d,0,(int)n)        /*  flavors. */
  1455. X#$rename RENAME        /* is rename() a system call? */
  1456. X#$ftruncate FTRUNCATE    /* is ftruncate() available? */
  1457. X#$usleep USLEEP        /* do we have usleep? */
  1458. X#$uselect USELECT     /* should we use select to emulate usleep? */
  1459. X#$strftime STRFTIME    /* is strftime() available? */
  1460. X#$chsize CHSIZE        /* is chsize() available? */
  1461. X#$tzset TZSET        /* modern timezone functions? */
  1462. X#$novoid void int    /* is void to be avoided? */
  1463. X#$novfork vfork fork    /* is vfork too virtual? */
  1464. X#$sunos4 SUNOS4        /* running SunOS 4.X? */
  1465. X#$eunice EUNICE        /* no linking? */
  1466. X#$eunice VMS        /* not currently used, here just in case */
  1467. X#$getcwd GETCWD        /* do we have getcwd()? */
  1468. X#$getwd GETWD        /* do we have getwd()? */
  1469. X#$setvbuf SETVBUF     /* do we have setvbuf()? */
  1470. X#$setbuffer SETBUFFER    /* do we have setbuffer()? */
  1471. X#$usendir USENDIR     /* include ndir.c? */
  1472. X#$libndir LIBNDIR     /* include /usr/include/ndir.h? */
  1473. X#define DIRTYPE $dirtype
  1474. X#ifndef USENDIR
  1475. X#define DIRINC $dirinc
  1476. X#endif
  1477. X#$mininact MININACT    /* include 2.10.2 optimization? */
  1478. X#$portable PORTABLE    /* do we do extra lookups to start up? */
  1479. X#$passnam PASSNAMES    /* do names come from the passwd file? */
  1480. X            /*  (undef to take name from ~/.fullname) */
  1481. X#$berknam BERKNAMES    /* if so, are they Berkeley format? */
  1482. X            /* (that is, ":name,stuff:") */
  1483. X#$usgnam USGNAMES    /* or are they USG format? */
  1484. X            /* (that is, ":stuff-name(stuff):") */
  1485. X#$whoami WHOAMI        /* should we include whoami.h? */
  1486. X#$rdchk RDCHK        /* do we have rdchk()? */
  1487. X#$termio TERMIO        /* is this a termio system? */
  1488. X#$termios TERMIOS     /* is this a termios system? */
  1489. X#$fcntl FCNTL        /* should we include fcntl.h? */
  1490. X#$ioctl IOCTL        /* are ioctl args all defined in one place? */
  1491. X#$ptem PTEM        /* has the ptem.h include file ? */
  1492. X#$normsig NORMSIG     /* use signal rather than sigset? */
  1493. X#$sigblock SIGBLOCK    /* use sigblock and sigsetmask */
  1494. X#$sighold HAVESIGHOLD    /* use sighold and sigrelse */
  1495. X#define SIGRET $sigret    /* what does signal() return? */
  1496. X#$havetlib HAVETERMLIB    /* do we have termlib-style routines? */
  1497. X#$getuidgid GETUIDGID    /* allow setuid (if possible) */
  1498. X#$getpwent GETPWENT    /* should we include getpwent? */
  1499. X#$internet INTERNET    /* does our mailer do INTERNET addressing? */
  1500. X#$gethostname GETHOSTNAME    /* do we have a gethostname function? */
  1501. X#$douname DOUNAME     /* do we have a uname function? */
  1502. X#$phostname PHOSTNAME "$hostcmd"    /* how to get host name with popen */
  1503. X#$norelay NORELAY     /* 2.10.3 doesn't have Relay-Version line */
  1504. X#$isrrn SERVER        /* rrn server code */
  1505. X#$isrrn SERVER_FILE "$serverfile"    /* news server file */
  1506. X#$syslog2 USESYSLOG $syslog    /* use syslog for mthreads' log messages */
  1507. X#$xthread XTHREAD     /* get thread files via NNTP */
  1508. XEOT
  1509. END_OF_FILE
  1510. if test 6846 -ne `wc -c <'config.h.SH'`; then
  1511.     echo shar: \"'config.h.SH'\" unpacked with wrong size!
  1512. fi
  1513. # end of 'config.h.SH'
  1514. fi
  1515. if test -f 'final.c' -a "${1}" != "-c" ; then 
  1516.   echo shar: Will not clobber existing file \"'final.c'\"
  1517. else
  1518. echo shar: Extracting \"'final.c'\" \(5349 characters\)
  1519. sed "s/^X//" >'final.c' <<'END_OF_FILE'
  1520. X/* $Id: final.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  1521. X *
  1522. X * $Log: final.c,v $
  1523. X * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  1524. X * Patchlevel 2 changes
  1525. X *
  1526. X * Revision 4.4  1991/09/09  20:18:23  sob
  1527. X * release 4.4
  1528. X *
  1529. X *
  1530. X * 
  1531. X */
  1532. X/* This software is Copyright 1991 by Stan Barber. 
  1533. X *
  1534. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  1535. X * use this software as long as: there is no monetary profit gained
  1536. X * specifically from the use or reproduction of this software, it is not
  1537. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  1538. X * included prominently in any copy made. 
  1539. X *
  1540. X * The author make no claims as to the fitness or correctness of this software
  1541. X * for any use whatsoever, and it is provided as is. Any use of this software
  1542. X * is at the user's own risk. 
  1543. X */
  1544. X
  1545. X#include "EXTERN.h"
  1546. X#include "common.h"
  1547. X#include "util.h"
  1548. X#include "term.h"
  1549. X#include "ng.h"
  1550. X#include "init.h"
  1551. X#include "bits.h"
  1552. X#include "last.h"
  1553. X#include "rcstuff.h"
  1554. X#include "ngdata.h"
  1555. X#include "artio.h"
  1556. X#ifdef SERVER
  1557. X#include "server.h"
  1558. X#endif
  1559. X#include "INTERN.h"
  1560. X#include "final.h"
  1561. X
  1562. void
  1563. final_init()
  1564. X{
  1565. X#ifdef SIGTSTP
  1566. X    sigset(SIGTSTP, stop_catcher);    /* job control signals */
  1567. X    sigset(SIGTTOU, stop_catcher);    /* job control signals */
  1568. X    sigset(SIGTTIN, stop_catcher);    /* job control signals */
  1569. X#endif
  1570. X
  1571. X    sigset(SIGINT, int_catcher);    /* always catch interrupts */
  1572. X#ifdef SIGHUP
  1573. X    sigset(SIGHUP, sig_catcher);    /* and hangups */
  1574. X#endif
  1575. X    sigset(SIGILL, sig_catcher);
  1576. X#ifdef SIGTRAP
  1577. X    sigset(SIGTRAP, sig_catcher);
  1578. X#endif
  1579. X    sigset(SIGFPE, sig_catcher);
  1580. X#ifdef SIGBUS
  1581. X    sigset(SIGBUS, sig_catcher);
  1582. X#endif
  1583. X    sigset(SIGSEGV, sig_catcher);
  1584. X#ifdef SIGSYS
  1585. X    sigset(SIGSYS, sig_catcher);
  1586. X#endif
  1587. X    sigset(SIGTERM, sig_catcher);
  1588. X#ifdef SIGXCPU
  1589. X    sigset(SIGXCPU, sig_catcher);
  1590. X#endif
  1591. X#ifdef SIGXFSZ
  1592. X    sigset(SIGXFSZ, sig_catcher);
  1593. X#endif
  1594. X#ifdef SIGWINCH
  1595. X    sigset(SIGWINCH, winch_catcher);
  1596. X#endif
  1597. X
  1598. X#ifndef lint
  1599. X#ifdef SIGEMT
  1600. X    sigignore(SIGEMT);
  1601. X#endif
  1602. X#endif /* lint */
  1603. X}
  1604. X
  1605. void                    /* very much void */
  1606. finalize(status)
  1607. int status;
  1608. X{
  1609. X    termlib_reset();
  1610. X    if (bizarre)
  1611. X    resetty();
  1612. X    if (lockname && *lockname)
  1613. X     UNLINK(lockname);
  1614. X#ifdef USETHREADS
  1615. X    if (tmpthread_group)
  1616. X    UNLINK(tmpthread_file);
  1617. X#endif
  1618. X#ifdef SERVER
  1619. X    if (*active_name)
  1620. X    UNLINK(active_name);
  1621. X    if (openart) {
  1622. X     char artname[MAXFILENAME];
  1623. X    char intrpwork[MAXFILENAME];
  1624. X    interp(intrpwork,MAXFILENAME,"%P");
  1625. X     sprintf(artname, "%s/rrn%ld.%d", intrpwork, (long)openart, getpid());
  1626. X     UNLINK(artname);
  1627. X    }
  1628. X    close_server();
  1629. X#endif /* SERVER */
  1630. X    if (status < 0) {
  1631. X    chdir("/usr/tmp");
  1632. X    sigset(SIGILL,SIG_DFL);
  1633. X    abort();
  1634. X    }
  1635. X    exit(status);
  1636. X}
  1637. X
  1638. X/* come here on interrupt */
  1639. X
  1640. SIGRET
  1641. int_catcher()
  1642. X{
  1643. X    sigset(SIGINT,int_catcher);
  1644. X#ifdef DEBUGGING
  1645. X    if (debug)
  1646. X    write(2,"int_catcher\n",12);
  1647. X#endif
  1648. X    if (!waiting) {
  1649. X    if (int_count) {        /* was there already an interrupt? */
  1650. X        write(2,"\nBye-bye.\n",10);
  1651. X        sig_catcher(0);        /* emulate the other signals */
  1652. X    }
  1653. X    int_count++;
  1654. X    }
  1655. X}
  1656. X
  1657. X/* come here on signal other than interrupt, stop, or cont */
  1658. X
  1659. SIGRET
  1660. sig_catcher(signo)
  1661. int signo;
  1662. X{
  1663. X#ifdef VERBOSE
  1664. X    static char *signame[] = {
  1665. X    "",
  1666. X    "HUP",
  1667. X    "INT",
  1668. X    "QUIT",
  1669. X    "ILL",
  1670. X    "TRAP",
  1671. X    "IOT",
  1672. X    "EMT",
  1673. X    "FPE",
  1674. X    "KILL",
  1675. X    "BUS",
  1676. X    "SEGV",
  1677. X    "SYS",
  1678. X    "PIPE",
  1679. X    "ALRM",
  1680. X    "TERM",
  1681. X    "???"
  1682. X#ifdef SIGTSTP
  1683. X    ,"STOP",
  1684. X    "TSTP",
  1685. X    "CONT",
  1686. X    "CHLD",
  1687. X    "TTIN",
  1688. X    "TTOU",
  1689. X    "TINT",
  1690. X    "XCPU",
  1691. X    "XFSZ"
  1692. X#ifdef SIGPROF
  1693. X    ,"VTALARM",
  1694. X    "PROF"
  1695. X#endif
  1696. X#endif
  1697. X    };
  1698. X#endif
  1699. X
  1700. X#ifdef DEBUGGING
  1701. X    if (debug) {
  1702. X    printf("\nSIG%s--.newsrc not restored in debug\n",signame[signo]);
  1703. X    finalize(-1);
  1704. X    }
  1705. X#endif
  1706. X    if (panic)
  1707. X    abort();
  1708. X    (void) sigset(SIGILL,SIG_DFL);
  1709. X    panic = TRUE;            /* disable terminal I/O */
  1710. X    if (doing_ng) {            /* need we reconstitute rc line? */
  1711. X#ifdef DELAYMARK
  1712. X    yankback();
  1713. X#endif
  1714. X    restore_ng();            /* then do so (hope this works) */
  1715. X    }
  1716. X    doing_ng = FALSE;
  1717. X    if (rc_changed)            /* need we write .newsrc out? */
  1718. X    write_rc();            /* then do so */
  1719. X    rc_changed = FALSE;
  1720. X#ifdef SIGHUP
  1721. X    if (signo != SIGHUP)
  1722. X#endif
  1723. X#ifdef VERBOSE
  1724. X    IF(verbose)
  1725. X        printf("\nCaught %s%s--.newsrc restored\n",
  1726. X        signo ? "a SIG" : "an internal error", signame[signo]);
  1727. X    ELSE
  1728. X#endif
  1729. X#ifdef TERSE
  1730. X        printf("\nSignal %d--bye bye\n",signo);
  1731. X#endif
  1732. X    switch (signo) {
  1733. X#ifdef SIGBUS
  1734. X    case SIGBUS:
  1735. X#endif
  1736. X    case SIGILL:
  1737. X    case SIGSEGV:
  1738. X    finalize(-signo);
  1739. X    }
  1740. X    finalize(1);                /* and blow up */
  1741. X}
  1742. X
  1743. X#ifdef SIGTSTP
  1744. X/* come here on stop signal */
  1745. X
  1746. SIGRET
  1747. stop_catcher(signo)
  1748. int signo;
  1749. X{
  1750. X    if (!waiting) {
  1751. X    checkpoint_rc();    /* good chance of crash while stopped */
  1752. X    if (clear_on_stop) {
  1753. X        clear();
  1754. X        putchar('\n') FLUSH;
  1755. X    }
  1756. X    termlib_reset();
  1757. X    resetty();        /* this is the point of all this */
  1758. X#ifdef DEBUGGING
  1759. X    if (debug)
  1760. X        write(2,"stop_catcher\n",13);
  1761. X#endif
  1762. X    sigset(signo,SIG_DFL);    /* enable stop */
  1763. X#ifdef SIGBLOCK
  1764. X    sigsetmask(sigblock(0) & ~(1 << (signo-1)));
  1765. X#endif
  1766. X    kill(0,signo);        /* and do the stop */
  1767. X        savetty();
  1768. X#ifdef MAILCALL
  1769. X        mailcount = 0;            /* force recheck */
  1770. X#endif
  1771. X        if (!panic) {
  1772. X        if (!waiting) {
  1773. X        termlib_init();
  1774. X            noecho();            /* set no echo */
  1775. X            crmode();            /* set cbreak mode */
  1776. X            forceme("\f");        /* cause a refresh */
  1777. X                    /* (defined only if TIOCSTI defined) */
  1778. X        errno = 0;            /* needed for getcmd */
  1779. X        }
  1780. X        }
  1781. X    }
  1782. X    sigset(signo,stop_catcher);    /* unenable the stop */
  1783. X}
  1784. X#endif
  1785. END_OF_FILE
  1786. if test 5349 -ne `wc -c <'final.c'`; then
  1787.     echo shar: \"'final.c'\" unpacked with wrong size!
  1788. fi
  1789. # end of 'final.c'
  1790. fi
  1791. if test -f 'head.c' -a "${1}" != "-c" ; then 
  1792.   echo shar: Will not clobber existing file \"'head.c'\"
  1793. else
  1794. echo shar: Extracting \"'head.c'\" \(8920 characters\)
  1795. sed "s/^X//" >'head.c' <<'END_OF_FILE'
  1796. X/* $Id: head.c,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  1797. X *
  1798. X * $Log: head.c,v $
  1799. X * Revision 4.4  1991/09/09  20:18:23  sob
  1800. X * release 4.4
  1801. X *
  1802. X *
  1803. X * 
  1804. X */
  1805. X/* This software is Copyright 1991 by Stan Barber. 
  1806. X *
  1807. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  1808. X * use this software as long as: there is no monetary profit gained
  1809. X * specifically from the use or reproduction of this software, it is not
  1810. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  1811. X * included prominently in any copy made. 
  1812. X *
  1813. X * The author make no claims as to the fitness or correctness of this software
  1814. X * for any use whatsoever, and it is provided as is. Any use of this software
  1815. X * is at the user's own risk. 
  1816. X */
  1817. X
  1818. X#include "EXTERN.h"
  1819. X#include "common.h"
  1820. X#include "artio.h"
  1821. X#include "bits.h"
  1822. X#ifdef SERVER
  1823. X#include "server.h"
  1824. X#endif
  1825. X#include "util.h"
  1826. X#include "INTERN.h"
  1827. X#include "head.h"
  1828. X
  1829. bool first_one;        /* is this the 1st occurance of this header line? */
  1830. X
  1831. static char htypeix[26] =
  1832. X    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  1833. X
  1834. void
  1835. head_init()
  1836. X{
  1837. X    register int i;
  1838. X
  1839. X    for (i=HEAD_FIRST+1; i<HEAD_LAST; i++)
  1840. X    htypeix[*htype[i].ht_name - 'a'] = i;
  1841. X}
  1842. X
  1843. X#ifdef DEBUGGING
  1844. void
  1845. dumpheader(where)
  1846. char *where;
  1847. X{
  1848. X    register int i;
  1849. X
  1850. X    printf("header: %d %s", parsed_art, where);
  1851. X
  1852. X    for (i=0; i<HEAD_LAST; i++) {
  1853. X    printf("%15s %4d %4d %03o\n",htype[i].ht_name,
  1854. X        htype[i].ht_minpos,
  1855. X        htype[i].ht_maxpos,
  1856. X        htype[i].ht_flags) FLUSH;
  1857. X    }
  1858. X}
  1859. X#endif
  1860. X
  1861. int
  1862. set_line_type(bufptr,colon)
  1863. char *bufptr;
  1864. register char *colon;
  1865. X{
  1866. X    char lc[LONGKEY+3];
  1867. X    register char *t, *f;
  1868. X    register int i, len;
  1869. X
  1870. X    if (colon-bufptr > LONGKEY+2)
  1871. X    return SOME_LINE;
  1872. X
  1873. X    for (t=lc,f=bufptr; f<colon; f++, t++) {
  1874. X    if (isspace(*f))
  1875. X    /* guard against space before : */
  1876. X        break;
  1877. X    *t = isupper(*f) ? tolower(*f) : *f;
  1878. X    }
  1879. X    *t = '\0';
  1880. X    f = lc;                /* get lc into register */
  1881. X    len = t - f;
  1882. X
  1883. X    /* now scan the headtype table, backwards so we don't have to supply an
  1884. X     * extra terminating value, using first letter as index, and length as
  1885. X     * optimization to avoid calling subroutine strEQ unnecessarily.  Hauls.
  1886. X     */
  1887. X    
  1888. X    if (islower(*f)) {
  1889. X    for (i = htypeix[*f - 'a']; *htype[i].ht_name == *f; --i) {
  1890. X        if (len == htype[i].ht_length && strEQ(f, htype[i].ht_name)) {
  1891. X        return i;
  1892. X        }
  1893. X    }
  1894. X    }
  1895. X    return SOME_LINE;
  1896. X}
  1897. X
  1898. void
  1899. start_header(artnum)
  1900. ART_NUM artnum;
  1901. X{
  1902. X    register int i;
  1903. X
  1904. X#ifdef DEBUGGING
  1905. X    if (debug & 4)
  1906. X    dumpheader("start_header\n");
  1907. X#endif
  1908. X    for (i=0; i<HEAD_LAST; i++) {
  1909. X    htype[i].ht_minpos = -1;
  1910. X    htype[i].ht_maxpos = 0;
  1911. X    }
  1912. X    in_header = SOME_LINE;
  1913. X    first_one = FALSE;
  1914. X#ifdef ASYNC_PARSE
  1915. X    parsed_art = artnum;
  1916. X#endif
  1917. X}
  1918. X
  1919. bool
  1920. parseline(art_buf,newhide,oldhide)
  1921. char *art_buf;
  1922. int newhide, oldhide;
  1923. X{
  1924. X    if (*art_buf == ' ' || *art_buf == '\t')
  1925. X                    /* header continuation line? */
  1926. X    return oldhide;
  1927. X    else {                /* maybe another header line */
  1928. X    char *s;
  1929. X
  1930. X    if (first_one) {        /* did we just pass 1st occurance? */
  1931. X        first_one = FALSE;
  1932. X        htype[in_header].ht_maxpos = artpos;
  1933. X                    /* remember where line left off */
  1934. X    }
  1935. X    s = index(art_buf,':');
  1936. X    if (s == Nullch) {
  1937. X                /* is it the end of the header? */
  1938. X        htype[PAST_HEADER].ht_minpos =
  1939. X        (*art_buf == '\n') ? ftell(artfp) : artpos;
  1940. X                /* remember where body starts */
  1941. X        in_header = PAST_HEADER;
  1942. X    }
  1943. X    else {    /* it is a new header line */
  1944. X        in_header = set_line_type(art_buf,s);
  1945. X        first_one = (htype[in_header].ht_minpos < 0);
  1946. X        if (first_one)
  1947. X        htype[in_header].ht_minpos = artpos;
  1948. X#ifdef DEBUGGING
  1949. X        if (debug & 4)
  1950. X        dumpheader(art_buf);
  1951. X#endif
  1952. X        if (htype[in_header].ht_flags & HT_HIDE)
  1953. X        return newhide;
  1954. X    }
  1955. X    }
  1956. X    return FALSE;            /* don't hide this line */
  1957. X}
  1958. X
  1959. X#ifdef ASYNC_PARSE
  1960. int
  1961. parse_maybe(artnum)
  1962. ART_NUM artnum;
  1963. X{
  1964. X    char tmpbuf[LBUFLEN];
  1965. X
  1966. X    if (parsed_art == artnum)
  1967. X    return 0;
  1968. X    /* no maybe about it now */
  1969. X#ifdef SERVER
  1970. X    if (nntpopen(artnum,GET_HEADER) == Nullfp) {
  1971. X#else
  1972. X    if (artopen(artnum) == Nullfp) {
  1973. X#endif
  1974. X    return -1;
  1975. X    }
  1976. X    start_header(artnum);
  1977. X    while (in_header) {
  1978. X    artpos = ftell(artfp);
  1979. X    if (fgets(tmpbuf,LBUFLEN,artfp) == Nullch)
  1980. X        break;
  1981. X    parseline(tmpbuf,FALSE,FALSE);
  1982. X    }
  1983. X    in_header = PAST_HEADER;
  1984. X    return 0;
  1985. X}
  1986. X#endif
  1987. X
  1988. X/* get the subject line for an article */
  1989. X
  1990. char *
  1991. fetchsubj(artnum,current_subject,copy)
  1992. ART_NUM artnum;                /* article to get subject from */
  1993. bool_int current_subject;        /* is it in a parsed header? */
  1994. bool_int copy;                /* do you want it savestr()ed? */
  1995. X{
  1996. X    char *s = Nullch, *t;
  1997. X#ifdef SERVER
  1998. X    static int xhdr = 1;        /* Can we use xhdr command? */
  1999. X    int eoo;                /* End of server output */
  2000. X#endif /* SERVER */
  2001. X
  2002. X#ifdef CACHESUBJ
  2003. X    if (!subj_list) {
  2004. X    register ART_NUM i;
  2005. X    
  2006. X
  2007. X#ifndef lint
  2008. X    subj_list =
  2009. X      (char**)safemalloc((MEM_SIZE)((OFFSET(lastart)+2)*sizeof(char *)));
  2010. X#endif /* lint */
  2011. X    for (i=0; i<=OFFSET(lastart); i++)
  2012. X        subj_list[i] = Nullch;
  2013. X    }
  2014. X    if (!artnum || artnum > lastart)
  2015. X    s = nullstr;
  2016. X    else
  2017. X    s = subj_list[OFFSET(artnum)];
  2018. X#endif
  2019. X    if (s == Nullch) {
  2020. X    if (current_subject) {
  2021. X        s = fetchlines(artnum,SUBJ_LINE);
  2022. X#ifdef CACHESUBJ
  2023. X        subj_list[OFFSET(artnum)] = s;
  2024. X#endif
  2025. X    }
  2026. X    else {
  2027. X        s = safemalloc((MEM_SIZE)LBUFLEN);
  2028. X        *s = '\0';
  2029. X#ifdef SERVER
  2030. X        if (xhdr) {
  2031. X            sprintf(ser_line, "XHDR subject %ld", artnum);
  2032. X            put_server(ser_line);
  2033. X#ifdef DEBUGGING
  2034. X        if (debug & DEB_NNTP)
  2035. X            printf(">%s\n", ser_line) FLUSH;
  2036. X#endif
  2037. X        if (nntp_get(ser_line, sizeof (ser_line)) >= 0) {
  2038. X#ifdef DEBUGGING
  2039. X            if (debug & DEB_NNTP)
  2040. X                printf("<%s\n", ser_line) FLUSH;
  2041. X#endif
  2042. X            if (ser_line[0] == CHAR_FATAL) {
  2043. X                fprintf(stderr,"\nrrn: %s\n",ser_line);
  2044. X                finalize(1);
  2045. X/*                xhdr = 0; */
  2046. X            } else {
  2047. X                while (nntp_get(ser_line, sizeof (ser_line)) >= 0) {
  2048. X#ifdef DEBUGGING
  2049. X                if (debug & DEB_NNTP)
  2050. X                    printf("<%s\n", ser_line) FLUSH;
  2051. X#endif
  2052. X                if (ser_line[0] == '.')
  2053. X                    break;
  2054. X                else {
  2055. X                    t = index(ser_line, ' ');
  2056. X                    if (t++) {
  2057. X                    strcpy(s, t);
  2058. X                    if (t = index(s, '\r'))
  2059. X                        *t = '\0';
  2060. X                    }
  2061. X                }
  2062. X                }
  2063. X            }
  2064. X        } else {
  2065. X            fprintf(stderr,
  2066. X            "\nrrn: Unexpected close of server socket.\n");
  2067. X            finalize(1);
  2068. X        }
  2069. X        }
  2070. X
  2071. X        if (!xhdr) {
  2072. X        sprintf(ser_line, "HEAD %ld", artnum);
  2073. X        put_server(ser_line);
  2074. X#ifdef DEBUGGING
  2075. X        if (debug & DEB_NNTP)
  2076. X            printf(">%s\n", ser_line) FLUSH;
  2077. X#endif
  2078. X        eoo = 0;
  2079. X        if (nntp_get(ser_line, sizeof (ser_line)) >= 0 && 
  2080. X            ser_line[0] == CHAR_OK) {
  2081. X            do {
  2082. X            if (nntp_get(s, LBUFLEN) < 0 || (*s == '.')) {
  2083. X            strcpy(s, "Title: \n");
  2084. X            eoo = 1;
  2085. X                }
  2086. X            } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8));
  2087. X
  2088. X            if (!eoo)
  2089. X            while (nntp_get(ser_line, sizeof (ser_line)) >= 0 &&
  2090. X                ser_line[0] != '.');
  2091. X            t = index(s,':')+1;
  2092. X            while (*t == ' ') t++;
  2093. X            strcpy(s, t);
  2094. X            }
  2095. X        }
  2096. X#else /* not SERVER */
  2097. X        if (artopen(artnum) != Nullfp) {
  2098. X        do {
  2099. X            if (fgets(s,LBUFLEN,artfp) == Nullch)
  2100. X            strcpy(s, "Title: \n");
  2101. X        } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8));
  2102. X
  2103. X        s[strlen(s)-1] = '\0';
  2104. X        t = index(s,':')+1;
  2105. X        while (*t == ' ') t++;
  2106. X        strcpy(s, t);
  2107. X        }
  2108. X#endif
  2109. X        s = saferealloc(s, (MEM_SIZE)strlen(s)+1);
  2110. X#ifdef CACHESUBJ
  2111. X        subj_list[OFFSET(artnum)] = s;
  2112. X#endif 
  2113. X    }
  2114. X    }
  2115. X#ifdef CACHESUBJ
  2116. X    if (copy) {
  2117. X    t = savestr(s);
  2118. X    return t;
  2119. X    }
  2120. X    else
  2121. X    return s;
  2122. X#else
  2123. X    if (copy)
  2124. X    return s;
  2125. X    else {
  2126. X    safecpy(cmd_buf,s,CBUFLEN);    /* hope this is okay--we're */
  2127. X    free(s);
  2128. X    return cmd_buf;            /* really scraping for space here */
  2129. X    }
  2130. X#endif
  2131. X}
  2132. X
  2133. X/* get header lines from an article */
  2134. X
  2135. char *
  2136. fetchlines(artnum,which_line)
  2137. ART_NUM artnum;                /* article to get line from */
  2138. int which_line;                /* type of line desired */
  2139. X{
  2140. X    char *newbuf, *t, tmp_buf[LBUFLEN];
  2141. X    register ART_POS curpos;
  2142. X    int size;
  2143. X    register ART_POS firstpos;
  2144. X    register ART_POS lastpos;
  2145. X    
  2146. X#ifdef ASYNC_PARSE
  2147. X    if (parse_maybe(artnum))
  2148. X    artnum = 0;
  2149. X#endif
  2150. X    firstpos = htype[which_line].ht_minpos;
  2151. X    lastpos = htype[which_line].ht_maxpos;
  2152. X#ifdef SERVER
  2153. X    if (!artnum || firstpos < 0 || nntpopen(artnum,GET_HEADER) == Nullfp) {
  2154. X#else
  2155. X    if (!artnum || firstpos < 0 || artopen(artnum) == Nullfp) {
  2156. X#endif
  2157. X    newbuf = safemalloc((unsigned int)1);
  2158. X    *newbuf = '\0';
  2159. X    return newbuf;
  2160. X    }
  2161. X#ifndef lint
  2162. X    size = lastpos - firstpos + 1;
  2163. X#else
  2164. X    size = Null(int);
  2165. X#endif /* lint */
  2166. X#ifdef DEBUGGING
  2167. X    if (debug && (size < 1 || size > 1000)) {
  2168. X    printf("Firstpos = %ld, lastpos = %ld\n",(long)firstpos,(long)lastpos);
  2169. X    gets(tmp_buf);
  2170. X    }
  2171. X#endif
  2172. X    newbuf = safemalloc((unsigned int)size);
  2173. X    *newbuf = '\0';
  2174. X    fseek(artfp,firstpos,0);
  2175. X    for (curpos = firstpos; curpos < lastpos; curpos = ftell(artfp)) {
  2176. X    if (fgets(tmp_buf,LBUFLEN,artfp) == Nullch)
  2177. X        break;
  2178. X    if (*tmp_buf == ' ' || *tmp_buf == '\t')
  2179. X        t = tmp_buf;
  2180. X    else {
  2181. X        t = index(tmp_buf,':');
  2182. X        if (t == Nullch)
  2183. X        break;
  2184. X        t++;
  2185. X    }
  2186. X    while (*t == ' ' || *t == '\t') t++;
  2187. X    safecat(newbuf,t,size);
  2188. X    }
  2189. X    return newbuf;
  2190. X}
  2191. X
  2192. END_OF_FILE
  2193. if test 8920 -ne `wc -c <'head.c'`; then
  2194.     echo shar: \"'head.c'\" unpacked with wrong size!
  2195. fi
  2196. # end of 'head.c'
  2197. fi
  2198. if test -f 'init.c' -a "${1}" != "-c" ; then 
  2199.   echo shar: Will not clobber existing file \"'init.c'\"
  2200. else
  2201. echo shar: Extracting \"'init.c'\" \(6682 characters\)
  2202. sed "s/^X//" >'init.c' <<'END_OF_FILE'
  2203. X/* $Id: init.c,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  2204. X *
  2205. X * $Log: init.c,v $
  2206. X * Revision 4.4  1991/09/09  20:18:23  sob
  2207. X * release 4.4
  2208. X *
  2209. X *
  2210. X * 
  2211. X */
  2212. X/* This software is Copyright 1991 by Stan Barber. 
  2213. X *
  2214. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  2215. X * use this software as long as: there is no monetary profit gained
  2216. X * specifically from the use or reproduction of this software, it is not
  2217. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  2218. X * included prominently in any copy made. 
  2219. X *
  2220. X * The author make no claims as to the fitness or correctness of this software
  2221. X * for any use whatsoever, and it is provided as is. Any use of this software
  2222. X * is at the user's own risk. 
  2223. X */
  2224. X
  2225. X#include "EXTERN.h"
  2226. X#include "common.h"
  2227. X#include "util.h"
  2228. X#include "final.h"
  2229. X#include "term.h"
  2230. X#include "last.h"
  2231. X#include "rn.h"
  2232. X#include "rcstuff.h"
  2233. X#include "ngdata.h"
  2234. X#include "only.h"
  2235. X#include "intrp.h"
  2236. X#include "addng.h"
  2237. X#include "sw.h"
  2238. X#include "art.h"
  2239. X#include "artsrch.h"
  2240. X#include "artio.h"
  2241. X#include "backpage.h"
  2242. X#include "bits.h"
  2243. X#include "cheat.h"
  2244. X#include "head.h"
  2245. X#include "help.h"
  2246. X#include "kfile.h"
  2247. X#include "ngsrch.h"
  2248. X#include "ngstuff.h"
  2249. X#include "rcln.h"
  2250. X#include "respond.h"
  2251. X#ifdef SERVER
  2252. X#include "server.h"
  2253. X#endif
  2254. X#ifdef USETHREADS
  2255. X#include "threads.h"
  2256. X#include "rthreads.h"
  2257. X#endif
  2258. X#include "ng.h"
  2259. X#include "decode.h"
  2260. X#include "INTERN.h"
  2261. X#include "init.h"
  2262. X
  2263. bool
  2264. initialize(argc,argv)
  2265. int argc;
  2266. char *argv[];
  2267. X{
  2268. X    char *tcbuf;
  2269. X    register bool foundany = FALSE;
  2270. X    long time();
  2271. X#ifdef SERVER
  2272. X    char *server;
  2273. X    int response;
  2274. X#endif
  2275. X#ifdef NOLINEBUF
  2276. X    static char std_out_buf[BUFSIZ];    /* must be static or malloced */
  2277. X
  2278. X    setbuf(stdout, std_out_buf);
  2279. X#endif
  2280. X
  2281. X    tcbuf = safemalloc(1024);        /* make temp buffer for termcap and */
  2282. X                    /* other initialization stuff */
  2283. X    
  2284. X    /* init terminal */
  2285. X    
  2286. X    term_init();            /* must precede sw_init() so that */
  2287. X                    /* ospeed is set for baud-rate */
  2288. X                    /* switches.  Actually terminal */
  2289. X                    /* mode setting is in term_set() */
  2290. X
  2291. X    /* we have to know rnlib to look up global switches in %X/INIT */
  2292. X
  2293. X    lib = savestr(filexp(LIB));
  2294. X    rnlib = savestr(filexp(RNLIB));
  2295. X
  2296. X    /* decode switches */
  2297. X
  2298. X    sw_init(argc,argv,&tcbuf);          /* must not do % interps! */
  2299. X                    /* (but may mung environment) */
  2300. X
  2301. X    /* init signals, status flags */
  2302. X
  2303. X    final_init();
  2304. X    
  2305. X    /* start up file expansion and the % interpreter */
  2306. X
  2307. X    intrp_init(tcbuf);
  2308. X    
  2309. X    /* now make sure we have a current working directory */
  2310. X
  2311. X    if (!checkflag)
  2312. X    cwd_check();
  2313. X    
  2314. X    /* now that we know where to save things, cd to news directory */
  2315. X
  2316. X    if (chdir(spool)) {
  2317. X    printf(nocd,spool) FLUSH;
  2318. X    finalize(1);
  2319. X    }
  2320. X
  2321. X    /* if we aren't just checking, turn off echo */
  2322. X
  2323. X    if (!checkflag)
  2324. X    term_set(tcbuf);
  2325. X
  2326. X    /* get info on last rn run, if any */
  2327. X
  2328. X    if (!checkflag)
  2329. X    last_init(tcbuf);
  2330. X
  2331. X    free(tcbuf);            /* recover 1024 bytes */
  2332. X
  2333. X    /* make sure we are the sole possessors of .newsrc */
  2334. X
  2335. X    if (!checkflag)
  2336. X    lock_check();
  2337. X
  2338. X    /* check for news news */
  2339. X
  2340. X    if (!checkflag)
  2341. X    newsnews_check();
  2342. X
  2343. X#ifdef SERVER
  2344. X
  2345. X    /* open connection to server if appropriate */
  2346. X
  2347. X    if ((server = get_server_name(1)) == NULL)
  2348. X    finalize(1);
  2349. X
  2350. X    response = server_init(server);
  2351. X    if (response < 0) {
  2352. X    fprintf(stderr,
  2353. X        "Couldn't connect to %s news server, try again later.\n",
  2354. X        server);
  2355. X    finalize(1);
  2356. X    }
  2357. X
  2358. X    if (handle_server_response(response, server) < 0)
  2359. X    finalize(1);
  2360. X
  2361. X#endif
  2362. X
  2363. X    /* open active file, etc. */
  2364. X
  2365. X    ngdata_init();
  2366. X
  2367. X    /* now read in the .newsrc file */
  2368. X
  2369. X    foundany = rcstuff_init();
  2370. X
  2371. X    /* it looks like we will actually read something, so init everything */
  2372. X
  2373. X    addng_init();
  2374. X    art_init();
  2375. X    artio_init();
  2376. X    artsrch_init();
  2377. X    backpage_init();
  2378. X    bits_init();
  2379. X    cheat_init();
  2380. X    head_init();
  2381. X    help_init();
  2382. X    kfile_init();
  2383. X    ng_init();
  2384. X    ngsrch_init();
  2385. X    ngstuff_init();
  2386. X    only_init();
  2387. X    rcln_init();
  2388. X    respond_init();
  2389. X    rn_init();
  2390. X    search_init();
  2391. X    decode_init();
  2392. X#ifdef USETHREADS
  2393. X    thread_init();
  2394. X#endif
  2395. X    util_init();
  2396. X
  2397. X#ifdef FINDNEWNG
  2398. X    /*
  2399. X     * Skip this check if the -q flag was given.
  2400. X     */
  2401. X    if (!quickstart) {
  2402. X    if (find_new_groups()) {    /* did we add any new groups? */
  2403. X        foundany = TRUE;        /* let main() know */
  2404. X        starthere = 0;        /* start ng scan from the top */
  2405. X    }
  2406. X    }
  2407. X#endif
  2408. X    time(&lasttime);            /* remember when we inited-- */
  2409. X                    /* ends up back in .rnlast */
  2410. X    writelast();            /* in fact, put it there now */
  2411. X
  2412. X#ifdef FINDNEWNG
  2413. X# ifdef ONLY
  2414. X    if (maxngtodo)            /* patterns on command line? */
  2415. X    foundany |= scanactive();
  2416. X# endif
  2417. X#endif
  2418. X
  2419. X    return foundany;
  2420. X}
  2421. X
  2422. X/* make sure there is no rn out there already */
  2423. X
  2424. void
  2425. lock_check()
  2426. X{
  2427. X    lockname = savestr(filexp(LOCKNAME));
  2428. X    if (!checkflag) {
  2429. X    tmpfp = fopen(lockname,"r");
  2430. X    if (tmpfp != Nullfp) {
  2431. X        int processnum;
  2432. X    
  2433. X        fgets(buf,LBUFLEN,tmpfp);
  2434. X        fclose(tmpfp);
  2435. X        processnum = atoi(buf);
  2436. X#ifdef VERBOSE
  2437. X        IF(verbose)
  2438. X        printf("You seem to have left a trn running, process %d.\n",
  2439. X            processnum) FLUSH;
  2440. X        ELSE
  2441. X#endif
  2442. X#ifdef TERSE
  2443. X        printf("Trn left running, #%d.\n", processnum) FLUSH;
  2444. X#endif
  2445. X        if (kill(processnum, SIGEMT)) {
  2446. X                    /* does process not exist? */
  2447. X                    /* (rn ignores SIGEMT) */
  2448. X        sleep(2);
  2449. X#ifdef VERBOSE
  2450. X        IF(verbose)
  2451. X            fputs("\n\
  2452. That process does not seem to exist anymore.  The count of read articles\n\
  2453. may be incorrect in the last newsgroup accessed by that other (defunct)\n\
  2454. process.\n\n",stdout) FLUSH;
  2455. X        ELSE
  2456. X#endif
  2457. X#ifdef TERSE
  2458. X            fputs("\nProcess crashed.\n",stdout) FLUSH;
  2459. X#endif
  2460. X        if (*lastngname) {
  2461. X#ifdef VERBOSE
  2462. X            IF(verbose)
  2463. X            printf("(The last newsgroup accessed was %s.)\n\n",
  2464. X            lastngname) FLUSH;
  2465. X            ELSE
  2466. X#endif
  2467. X#ifdef TERSE
  2468. X            printf("(In %s.)\n\n",lastngname) FLUSH;
  2469. X#endif
  2470. X        }
  2471. X        get_anything();
  2472. X        putchar('\n') FLUSH;
  2473. X        }
  2474. X        else {
  2475. X#ifdef VERBOSE
  2476. X        IF(verbose)
  2477. X            fputs("\n\
  2478. You may not have two copies of [t]rn running simultaneously.  Goodbye.\n\
  2479. X",stdout) FLUSH;
  2480. X        ELSE
  2481. X#endif
  2482. X#ifdef TERSE
  2483. X            fputs("\nCan't start another.\n",stdout) FLUSH;
  2484. X#endif
  2485. X               if (bizarre)
  2486. X                 resetty();
  2487. X        exit(0);
  2488. X        }
  2489. X    }
  2490. X    tmpfp = fopen(lockname,"w");
  2491. X    if (tmpfp == Nullfp) {
  2492. X        printf(cantcreate,lockname) FLUSH;
  2493. X        sig_catcher(0);
  2494. X    }
  2495. X    fprintf(tmpfp,"%d\n",getpid());
  2496. X    fclose(tmpfp);
  2497. X    }
  2498. X}
  2499. X
  2500. void
  2501. newsnews_check()
  2502. X{
  2503. X    char *newsnewsname = filexp(NEWSNEWSNAME);
  2504. X
  2505. X    if ((tmpfp = fopen(newsnewsname,"r")) != Nullfp) {
  2506. X    fstat(fileno(tmpfp),&filestat);
  2507. X    if (filestat.st_mtime > lasttime) {
  2508. X        while (fgets(buf,sizeof(buf),tmpfp) != Nullch)
  2509. X        fputs(buf,stdout) FLUSH;
  2510. X        get_anything();
  2511. X        putchar('\n') FLUSH;
  2512. X    }
  2513. X    fclose(tmpfp);
  2514. X    }
  2515. X}
  2516. END_OF_FILE
  2517. if test 6682 -ne `wc -c <'init.c'`; then
  2518.     echo shar: \"'init.c'\" unpacked with wrong size!
  2519. fi
  2520. # end of 'init.c'
  2521. fi
  2522. if test -f 'kfile.c' -a "${1}" != "-c" ; then 
  2523.   echo shar: Will not clobber existing file \"'kfile.c'\"
  2524. else
  2525. echo shar: Extracting \"'kfile.c'\" \(7380 characters\)
  2526. sed "s/^X//" >'kfile.c' <<'END_OF_FILE'
  2527. X/* $Id: kfile.c,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  2528. X *
  2529. X * $Log: kfile.c,v $
  2530. X * Revision 4.4  1991/09/09  20:18:23  sob
  2531. X * release 4.4
  2532. X *
  2533. X *
  2534. X * 
  2535. X */
  2536. X/* This software is Copyright 1991 by Stan Barber. 
  2537. X *
  2538. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  2539. X * use this software as long as: there is no monetary profit gained
  2540. X * specifically from the use or reproduction of this software, it is not
  2541. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  2542. X * included prominently in any copy made. 
  2543. X *
  2544. X * The author make no claims as to the fitness or correctness of this software
  2545. X * for any use whatsoever, and it is provided as is. Any use of this software
  2546. X * is at the user's own risk. 
  2547. X */
  2548. X
  2549. X#include "EXTERN.h"
  2550. X#include "common.h"
  2551. X#include "term.h"
  2552. X#include "util.h"
  2553. X#include "artsrch.h"
  2554. X#include "ng.h"
  2555. X#include "bits.h"
  2556. X#include "intrp.h"
  2557. X#include "ngstuff.h"
  2558. X#include "rcstuff.h"
  2559. X#include "rn.h"
  2560. X#ifdef USETHREADS
  2561. X#include "threads.h"
  2562. X#include "rthreads.h"
  2563. X#endif
  2564. X#include "INTERN.h"
  2565. X#include "kfile.h"
  2566. X
  2567. static bool exitcmds = FALSE;
  2568. X
  2569. void
  2570. kfile_init()
  2571. X{
  2572. X    ;
  2573. X}
  2574. X
  2575. X#ifndef KILLFILES
  2576. int
  2577. edit_kfile()
  2578. X{
  2579. X    notincl("^K");
  2580. X    return -1;
  2581. X}
  2582. X
  2583. X#else /* KILLFILES */
  2584. X
  2585. char killglobal[] = KILLGLOBAL;
  2586. char killlocal[] = KILLLOCAL;
  2587. X
  2588. void
  2589. mention(str)
  2590. char *str;
  2591. X{
  2592. X#ifdef VERBOSE
  2593. X    IF(verbose) {
  2594. X#ifdef NOFIREWORKS
  2595. X    no_sofire();
  2596. X#endif
  2597. X    standout();
  2598. X    fputs(str,stdout);
  2599. X    un_standout();
  2600. X    putchar('\n');
  2601. X    }
  2602. X    ELSE
  2603. X#endif
  2604. X#ifdef TERSE
  2605. X    putchar('.');
  2606. X#endif
  2607. X    fflush(stdout);
  2608. X}
  2609. X
  2610. bool kill_mentioned;
  2611. X
  2612. int
  2613. do_kfile(kfp,entering)
  2614. XFILE *kfp;
  2615. int entering;
  2616. X{
  2617. X#ifdef USETHREADS
  2618. X    int i;
  2619. X    ART_NUM kill_thread;
  2620. X#endif
  2621. X
  2622. X    art = lastart+1;
  2623. X    fseek(kfp,0L,0);            /* rewind file */
  2624. X    while (fgets(buf,LBUFLEN,kfp) != Nullch) {
  2625. X    buf[strlen(buf)-1] = '\0';
  2626. X    if (strnEQ(buf,"THRU",4)) {
  2627. X        ART_NUM tmpart;
  2628. X
  2629. X        tmpart = atol(buf+4)+1;
  2630. X        if (tmpart < absfirst)
  2631. X        tmpart = absfirst;
  2632. X        check_first(tmpart);
  2633. X        firstart = tmpart;
  2634. X        continue;
  2635. X    }
  2636. X    if (*buf == 'X') {        /* exit command? */
  2637. X        if (entering) {
  2638. X        exitcmds = TRUE;
  2639. X        continue;
  2640. X        }
  2641. X        strcpy(buf,buf+1);
  2642. X    }
  2643. X    else {
  2644. X        if (!entering)
  2645. X        continue;
  2646. X    }
  2647. X    if (*buf == '&') {
  2648. X        mention(buf);
  2649. X        switcheroo();
  2650. X    }
  2651. X    else if (*buf == '/' && firstart <= lastart) {
  2652. X        mention(buf);
  2653. X        kill_mentioned = TRUE;
  2654. X        switch (art_search(buf, (sizeof buf), FALSE)) {
  2655. X        case SRCH_ABORT:
  2656. X        continue;
  2657. X        case SRCH_INTR:
  2658. X#ifdef VERBOSE
  2659. X        IF(verbose)
  2660. X            printf("\n(Interrupted at article %ld)\n",(long)art)
  2661. X              FLUSH;
  2662. X        ELSE
  2663. X#endif
  2664. X#ifdef TERSE
  2665. X            printf("\n(Intr at %ld)\n",(long)art) FLUSH;
  2666. X#endif
  2667. X        return -1;
  2668. X        case SRCH_DONE:
  2669. X        break;
  2670. X        case SRCH_SUBJDONE:
  2671. X        fputs("\tsubject not found (???)\n",stdout) FLUSH;
  2672. X        break;
  2673. X        case SRCH_NOTFOUND:
  2674. X        fputs("\tnot found\n",stdout) FLUSH;
  2675. X        break;
  2676. X        case SRCH_FOUND:
  2677. X        fputs("\tfound\n",stdout) FLUSH;
  2678. X        }
  2679. X    }
  2680. X#ifdef USETHREADS
  2681. X    else if (*buf == 'T' && firstart <= lastart && p_roots) {
  2682. X        /* kill a thread by its root id number */
  2683. X        kill_thread = atol(buf+1);
  2684. X        for (i = 0; i < total.root; i++) {
  2685. X        if (p_roots[i].root_num == kill_thread) {
  2686. X            if (count_one_root(i) != 0) {
  2687. X            mention(buf);
  2688. X            kill_mentioned = TRUE;
  2689. X            printf("%ldx%d ",(long)kill_thread,
  2690. X                     root_article_cnts[i]);
  2691. X#ifdef VERBOSE
  2692. X            IF(verbose)
  2693. X                putchar('\n') FLUSH;
  2694. X#endif
  2695. X            p_art = p_articles + p_roots[i].articles;
  2696. X            art = p_art->num;
  2697. X            follow_thread('J');
  2698. X            }
  2699. X            break;
  2700. X        }
  2701. X        }
  2702. X    }
  2703. X#endif
  2704. X    }
  2705. X
  2706. X    return 0;
  2707. X}
  2708. X
  2709. void
  2710. kill_unwanted(starting,message,entering)
  2711. ART_NUM starting;
  2712. char *message;
  2713. int entering;
  2714. X{
  2715. X    bool intr = FALSE;            /* did we get an interrupt? */
  2716. X    ART_NUM oldfirst;
  2717. X    bool anytokill = (toread[ng] > 0);
  2718. X
  2719. X    if (localkfp || globkfp) {
  2720. X    if (!entering && !exitcmds)
  2721. X        return;
  2722. X    exitcmds = FALSE;
  2723. X    oldfirst = firstart;
  2724. X    firstart = starting;
  2725. X    clear();
  2726. X#ifdef VERBOSE
  2727. X# ifdef TERSE
  2728. X    if (message && (verbose || entering))
  2729. X# else
  2730. X    if (message)
  2731. X# endif
  2732. X#else
  2733. X    if (message && entering)
  2734. X#endif
  2735. X        fputs(message,stdout) FLUSH;
  2736. X
  2737. X    kill_mentioned = FALSE;
  2738. X    if (localkfp)
  2739. X        intr = do_kfile(localkfp,entering);
  2740. X    if (globkfp && !intr)
  2741. X        intr = do_kfile(globkfp,entering);
  2742. X    if (entering && localkfp && !intr)
  2743. X        setthru(lastart);
  2744. X    putchar('\n') FLUSH;
  2745. X    if (entering && kill_mentioned)
  2746. X#ifdef VERBOSE
  2747. X        IF(verbose)
  2748. X        get_anything();
  2749. X        ELSE
  2750. X#endif
  2751. X#ifdef TERSE
  2752. X        pad(just_a_sec);
  2753. X#endif
  2754. X    if (anytokill)            /* if there was anything to kill */
  2755. X        forcelast = FALSE;        /* allow for having killed it all */
  2756. X    firstart = oldfirst;
  2757. X    }
  2758. X}
  2759. X
  2760. void
  2761. setthru(thru)
  2762. ART_NUM thru;
  2763. X{
  2764. X    FILE *newkfp;
  2765. X    bool no_kills = 0;
  2766. X#ifdef USETHREADS
  2767. X    int i;
  2768. X    ART_NUM kill_thread;
  2769. X#endif
  2770. X
  2771. X    fseek(localkfp,0L,0);        /* rewind current file */
  2772. X    if (fgets(buf,LBUFLEN,localkfp) != Nullch
  2773. X     && (strnNE(buf,"THRU",4) || fgets(buf,LBUFLEN,localkfp) != Nullch))
  2774. X    fseek(localkfp,0L,0);
  2775. X    else
  2776. X    no_kills = 1;
  2777. X    strcpy(buf,filexp(getval("KILLLOCAL",killlocal)));
  2778. X    UNLINK(buf);            /* to prevent file reuse */
  2779. X    if (no_kills)
  2780. X    open_kfile(KF_LOCAL);        /* close file and reset open flag */
  2781. X    else if (newkfp = fopen(buf,"w")) {
  2782. X    fprintf(newkfp,"THRU %ld\n",(long)thru);
  2783. X    while (fgets(buf,LBUFLEN,localkfp) != Nullch) {
  2784. X        if (strnEQ(buf,"THRU",4))
  2785. X        continue;
  2786. X#ifdef USETHREADS
  2787. X        /* Leave out any outdated thread kills */
  2788. X        if (*buf == 'T' && p_roots) {
  2789. X        kill_thread = atol(buf+1);
  2790. X        for (i = 0; i < total.root; i++) {
  2791. X            if (p_roots[i].root_num == kill_thread) {
  2792. X            break;
  2793. X            }
  2794. X        }
  2795. X        if (i == total.root)
  2796. X            continue;
  2797. X        }
  2798. X#endif
  2799. X        fputs(buf,newkfp);
  2800. X    }
  2801. X    fclose(newkfp);
  2802. X    open_kfile(KF_LOCAL);        /* and reopen local file */
  2803. X    }
  2804. X    else
  2805. X    printf(cantcreate,buf) FLUSH;
  2806. X}
  2807. X
  2808. X/* edit KILL file for newsgroup */
  2809. X
  2810. int
  2811. edit_kfile()
  2812. X{
  2813. X    int r = -1;
  2814. X
  2815. X    if (in_ng)
  2816. X    strcpy(buf,filexp(getval("KILLLOCAL",killlocal)));
  2817. X    else
  2818. X    strcpy(buf,filexp(getval("KILLGLOBAL",killglobal)));
  2819. X    if ((r = makedir(buf,MD_FILE)) >= 0) {
  2820. X    sprintf(cmd_buf,"%s %s",
  2821. X        filexp(getval("VISUAL",getval("EDITOR",defeditor))),buf);
  2822. X    printf("\nEditing %s KILL file:\n%s\n",
  2823. X        (in_ng?"local":"global"),cmd_buf) FLUSH;
  2824. X    resetty();            /* make sure tty is friendly */
  2825. X    r = doshell(sh,cmd_buf);/* invoke the shell */
  2826. X    noecho();            /* and make terminal */
  2827. X    crmode();            /*   unfriendly again */
  2828. X    open_kfile(in_ng);
  2829. X    }
  2830. X    else
  2831. X    printf("Can't make %s\n",buf) FLUSH;
  2832. X    return r;
  2833. X}
  2834. X
  2835. void
  2836. open_kfile(local)
  2837. int local;
  2838. X{
  2839. X    char *kname = filexp(local ?
  2840. X    getval("KILLLOCAL",killlocal) :
  2841. X    getval("KILLGLOBAL",killglobal)
  2842. X    );
  2843. X    
  2844. X    stat(kname,&filestat);
  2845. X    if (!filestat.st_size)        /* nothing in the file? */
  2846. X    UNLINK(kname);            /* delete the file */
  2847. X    if (local) {
  2848. X    if (localkfp)
  2849. X        fclose(localkfp);
  2850. X    localkfp = fopen(kname,"r");
  2851. X    }
  2852. X    else {
  2853. X    if (globkfp)
  2854. X        fclose(globkfp);
  2855. X    globkfp = fopen(kname,"r");
  2856. X    }
  2857. X}
  2858. X
  2859. void
  2860. kf_append(cmd)
  2861. char *cmd;
  2862. X{
  2863. X    strcpy(cmd_buf,filexp(getval("KILLLOCAL",killlocal)));
  2864. X    if (makedir(cmd_buf,MD_FILE) >= 0) {
  2865. X#ifdef VERBOSE
  2866. X    IF(verbose)
  2867. X        printf("\nDepositing command in %s...",cmd_buf);
  2868. X    ELSE
  2869. X#endif
  2870. X#ifdef TERSE
  2871. X        printf("\n--> %s...",cmd_buf);
  2872. X#endif
  2873. X    fflush(stdout);
  2874. X    sleep(2);
  2875. X    if ((tmpfp = fopen(cmd_buf,"a")) != Nullfp) {
  2876. X        fseek(tmpfp,0L,2);        /* get to EOF for sure */
  2877. X        fprintf(tmpfp,"%s\n",cmd);
  2878. X        fclose(tmpfp);
  2879. X        fputs("done\n",stdout) FLUSH;
  2880. X    }
  2881. X    else
  2882. X        printf(cantopen,cmd_buf) FLUSH;
  2883. X    }
  2884. X}
  2885. X#endif /* KILLFILES */
  2886. END_OF_FILE
  2887. if test 7380 -ne `wc -c <'kfile.c'`; then
  2888.     echo shar: \"'kfile.c'\" unpacked with wrong size!
  2889. fi
  2890. # end of 'kfile.c'
  2891. fi
  2892. if test -f 'ngdata.c' -a "${1}" != "-c" ; then 
  2893.   echo shar: Will not clobber existing file \"'ngdata.c'\"
  2894. else
  2895. echo shar: Extracting \"'ngdata.c'\" \(8738 characters\)
  2896. sed "s/^X//" >'ngdata.c' <<'END_OF_FILE'
  2897. X/* $Id: ngdata.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  2898. X *
  2899. X * $Log: ngdata.c,v $
  2900. X * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  2901. X * Patchlevel 2 changes
  2902. X *
  2903. X * Revision 4.4.1.1  1991/09/25  19:38:08  sob
  2904. X * Some adaptions for CNEWS
  2905. X *
  2906. X * Revision 4.4  1991/09/09  20:23:31  sob
  2907. X * release 4.4
  2908. X *
  2909. X *
  2910. X * 
  2911. X */
  2912. X/* This software is Copyright 1991 by Stan Barber. 
  2913. X *
  2914. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  2915. X * use this software as long as: there is no monetary profit gained
  2916. X * specifically from the use or reproduction of this software, it is not
  2917. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  2918. X * included prominently in any copy made. 
  2919. X *
  2920. X * The author make no claims as to the fitness or correctness of this software
  2921. X * for any use whatsoever, and it is provided as is. Any use of this software
  2922. X * is at the user's own risk. 
  2923. X */
  2924. X
  2925. X#include "EXTERN.h"
  2926. X#include "common.h"
  2927. X#include "ndir.h"
  2928. X#include "rcstuff.h"
  2929. X#include "rn.h"
  2930. X#include "intrp.h"
  2931. X#include "final.h"
  2932. X#include "rcln.h"
  2933. X#include "util.h"
  2934. X#ifdef SERVER
  2935. X#include "server.h"
  2936. X#endif
  2937. X#include "INTERN.h"
  2938. X#include "ngdata.h"
  2939. X
  2940. void
  2941. ngdata_init()
  2942. X{
  2943. X    char *cp;
  2944. X
  2945. X    /* open the active file */
  2946. X
  2947. X#ifdef SERVER
  2948. X    put_server("LIST");        /* tell server we want the active file */
  2949. X    nntp_get(ser_line, sizeof(ser_line));
  2950. X    if (*ser_line != CHAR_OK) {        /* and then see if that's ok */
  2951. X    fprintf(stdout, "Can't get active file from server: \n%s\n", ser_line);
  2952. X    finalize(1);
  2953. X    }
  2954. X
  2955. X    cp = filexp("%P/rrnact.%$");    /* make a temporary name */
  2956. X    strcpy(active_name, cp);
  2957. X    actfp = fopen(active_name, "w+");    /* and get ready */
  2958. X    if (actfp == Nullfp) {
  2959. X    printf(cantopen,active_name) FLUSH;
  2960. X    finalize(1);
  2961. X    }
  2962. X
  2963. X    activeitems = 0;
  2964. X    while (1) {
  2965. X    if (nntp_get(ser_line, sizeof(ser_line)) < 0) {
  2966. X        printf("Can't get active file from server:\ntransfer failed after %d entries\n", activeitems);
  2967. X        finalize(1);
  2968. X    }
  2969. X    if (ser_line[0] == '.')        /* while there's another line */
  2970. X        break;            /* get it and write it to */
  2971. X    activeitems++;
  2972. X    fputs(ser_line, actfp);
  2973. X    putc('\n', actfp);
  2974. X    }
  2975. X
  2976. X    if (ferror(actfp)) {
  2977. X    printf("Error writing to active file %s.\n", active_name) FLUSH;
  2978. X    finalize(1);
  2979. X    }
  2980. X#else /* not SERVER */
  2981. X
  2982. X    cp = filexp(ACTIVE);
  2983. X    actfp = fopen(cp,"r");
  2984. X    if (actfp == Nullfp) {
  2985. X    printf(cantopen,cp) FLUSH;
  2986. X    finalize(1);
  2987. X    }
  2988. X    activeitems = 0;
  2989. X    /* count entries */
  2990. X    while(fgets(buf,LBUFLEN,actfp) != NULL)
  2991. X    activeitems++;
  2992. X#endif
  2993. X    if (fseek(actfp,0L,0) == -1) {    /* just get to the beginning */
  2994. X    printf("Error seeking in active file.\n") FLUSH;
  2995. X    finalize(1);
  2996. X    }
  2997. X
  2998. X    return;
  2999. X}
  3000. X
  3001. X/* find the maximum article number of a newsgroup */
  3002. X
  3003. ART_NUM
  3004. getngsize(num)
  3005. register NG_NUM num;
  3006. X{
  3007. X    register int len;
  3008. X    register char *nam;
  3009. X    char tmpbuf[80];
  3010. X    ART_POS oldsoft;
  3011. X
  3012. X    nam = rcline[num];
  3013. X    len = rcnums[num] - 1;
  3014. X    softtries++;
  3015. X#ifdef DEBUGGING
  3016. X    if (debug & DEB_SOFT_POINTERS)
  3017. X    printf("Softptr = %ld\n",(long)softptr[num]) FLUSH;
  3018. X#endif
  3019. X    oldsoft = softptr[num];
  3020. X    if ((softptr[num] = findact(tmpbuf, nam, len, (long)oldsoft)) >= 0) {
  3021. X    if (softptr[num] != oldsoft) {
  3022. X        softmisses++;
  3023. X        writesoft = TRUE;
  3024. X    }
  3025. X    }
  3026. X    else {
  3027. X    softptr[num] = 0;
  3028. X#ifdef USETHREADS
  3029. X    if (RCCHAR(rcchar[num]) == ':')
  3030. X#else
  3031. X    if (rcchar[num] == ':')        /* unsubscribe quietly */
  3032. X#endif
  3033. X        rcchar[num] = NEGCHAR;
  3034. X    return TR_BOGUS;        /* well, not so quietly, actually */
  3035. X    }
  3036. X    
  3037. X#ifdef DEBUGGING
  3038. X    if (debug & DEB_SOFT_POINTERS) {
  3039. X    printf("Should be %ld\n",(long)softptr[num]) FLUSH;
  3040. X    }
  3041. X#endif
  3042. X    {
  3043. X    register char *s;
  3044. X    ART_NUM tmp;
  3045. X
  3046. X    for (s=tmpbuf+len+1; isdigit(*s); s++) ;
  3047. X    if (tmp = atol(s))
  3048. X#ifdef MININACT
  3049. X#ifdef CACHEFIRST
  3050. X        abs1st[num] = tmp;
  3051. X#else
  3052. X        abs1st = tmp;
  3053. X#endif
  3054. X#endif
  3055. X    if (!in_ng) {
  3056. X        for (s++; isdigit(*s); s++) ;
  3057. X        while (isspace(*s)) s++;
  3058. X        switch (*s) {
  3059. X        case 'n': moderated = getval("NOPOSTRING"," (no posting)"); break;
  3060. X        case 'm': moderated = getval("MODSTRING", " (moderated)"); break;
  3061. X        /* This shouldn't even occur.  What are we doing in a non-existent
  3062. X           group?  Disallow it. */
  3063. X        case 'x': return TR_BOGUS;
  3064. X        /* what should be done about refiled groups?  rn shouldn't even
  3065. X           be in them (ie, if sci.aquaria is refiled to rec.aquaria, then
  3066. X           get the news there) */
  3067. X        case '=': return TR_BOGUS;
  3068. X        default: moderated = nullstr;
  3069. X        }
  3070. X    }
  3071. X    }
  3072. X#ifdef USETHREADS
  3073. X    {
  3074. X    ART_NUM last;
  3075. X
  3076. X    last = atol(tmpbuf+len+1);
  3077. X    return last >= ngmax[num] ? last : ngmax[num];
  3078. X    }
  3079. X#else
  3080. X    return atol(tmpbuf+len+1);
  3081. X#endif
  3082. X}
  3083. X
  3084. ACT_POS
  3085. findact(outbuf,nam,len,suggestion)
  3086. char *outbuf;
  3087. char *nam;
  3088. int len;
  3089. long suggestion;
  3090. X{
  3091. X    ACT_POS retval;
  3092. X
  3093. X    fseek(actfp,100000L,1);    /* hopefully this forces a reread */
  3094. X    if (suggestion == 0L || fseek(actfp,suggestion,0) < 0 ||
  3095. X      fgets(outbuf,80,actfp) == Nullch ||
  3096. X      outbuf[len] != ' ' ||
  3097. X      strnNE(outbuf,nam,len)) {
  3098. X#ifdef DEBUGGING
  3099. X    if (debug & DEB_SOFT_POINTERS)
  3100. X        printf("Missed, looking for %s in %sLen = %d\n",nam,outbuf,len)
  3101. X          FLUSH;
  3102. X#endif
  3103. X    fseek(actfp,0L,0);
  3104. X#ifndef lint
  3105. X    retval = (ACT_POS)ftell(actfp);
  3106. X#else
  3107. X    retval = Null(ACT_POS);
  3108. X#endif /* lint */
  3109. X    while (fgets(outbuf,80,actfp) != Nullch) {
  3110. X        if (outbuf[len] == ' ' && strnEQ(outbuf,nam,len))
  3111. X        return retval;
  3112. X#ifndef lint
  3113. X        retval = (ACT_POS) ftell(actfp);
  3114. X#endif /* lint */
  3115. X        if (ferror(actfp)) {
  3116. X        perror("error on active file"); /* something is wrong */
  3117. X        sig_catcher(0);
  3118. X        }
  3119. X    }
  3120. X    if(ferror(actfp)) {
  3121. X        perror("error on active file");
  3122. X        sig_catcher(0);
  3123. X    }
  3124. X    return (ACT_POS) -1;
  3125. X    }
  3126. X    else
  3127. X#ifndef lint
  3128. X    return (ACT_POS) suggestion;
  3129. X#else
  3130. X    return retval;
  3131. X#endif /* lint */
  3132. X    /*NOTREACHED*/
  3133. X}
  3134. X
  3135. X/* determine the absolutely first existing article number */
  3136. X#ifdef SERVER
  3137. ART_NUM
  3138. getabsfirst(ngnum,ngsize)
  3139. register NG_NUM ngnum;
  3140. ART_NUM ngsize;
  3141. X{
  3142. X    ART_NUM a1st;
  3143. X
  3144. X#ifdef CACHEFIRST
  3145. X    if (a1st = abs1st[ngnum])
  3146. X    return a1st;
  3147. X#endif
  3148. X#ifdef MININACT
  3149. X    getngsize(ngnum);
  3150. X# ifdef CACHEFIRST
  3151. X    return abs1st[ngnum];
  3152. X# else
  3153. X    return abs1st;
  3154. X# endif
  3155. X#else
  3156. X    getngsize(ngnum); /* set moderated as side effect */
  3157. X    sprintf(ser_line,"GROUP %s",rcline[ngnum]);
  3158. X    put_server(ser_line);
  3159. X    if (nntp_get(ser_line, sizeof(ser_line)) < 0) {
  3160. X    fprintf(stderr, "\nrrn: Unexpected close of server socket.\n");
  3161. X    finalize(1);
  3162. X    }
  3163. X    if (*ser_line == CHAR_FATAL){
  3164. X    fprintf(stderr,"\nrrn: %s\n",ser_line);
  3165. X    finalize(1);
  3166. X    }
  3167. X    if (*ser_line != CHAR_OK) {        /* and then see if that's ok */
  3168. X    a1st = ngsize+1;        /* nothing there */
  3169. X    }
  3170. X    (void) sscanf(ser_line,"%*d%*d%d",&a1st);
  3171. X# ifdef CACHEFIRST
  3172. X    abs1st[ngnum] = a1st;
  3173. X# endif
  3174. X    return a1st;
  3175. X#endif
  3176. X}
  3177. X/* we already know the lowest article number with NNTP */
  3178. ART_NUM
  3179. getngmin(dirname,floor)
  3180. char *dirname;
  3181. ART_NUM floor;
  3182. X{
  3183. X    return(floor);        /* dirname not used */
  3184. X}
  3185. X
  3186. X#else /*SERVER*/
  3187. X
  3188. ART_NUM
  3189. getabsfirst(ngnum,ngsize)
  3190. register NG_NUM ngnum;
  3191. ART_NUM ngsize;
  3192. X{
  3193. X    register ART_NUM a1st;
  3194. X#ifndef MININACT
  3195. X    char dirname[MAXFILENAME];
  3196. X#endif
  3197. X
  3198. X#ifdef CACHEFIRST
  3199. X    if (a1st = abs1st[ngnum])
  3200. X    return a1st;
  3201. X#endif
  3202. X#ifdef MININACT
  3203. X    getngsize(ngnum);
  3204. X# ifdef CACHEFIRST
  3205. X    return abs1st[ngnum];
  3206. X# else
  3207. X    return abs1st;
  3208. X# endif
  3209. X#else /* not MININACT */
  3210. X    getngsize(ngnum); /* set moderate as side effect */
  3211. X    sprintf(dirname,"%s/%s",spool,getngdir(rcline[ngnum]));
  3212. X    a1st = getngmin(dirname,0L);
  3213. X    if (!a1st)                /* nothing there at all? */
  3214. X    a1st = ngsize+1;        /* aim them at end of newsgroup */
  3215. X# ifdef CACHEFIRST
  3216. X    abs1st[ngnum] = a1st;
  3217. X# endif
  3218. X    return a1st;
  3219. X#endif /* MININACT */
  3220. X}
  3221. X
  3222. X/* scan a directory for minimum article number greater than floor */
  3223. X
  3224. ART_NUM
  3225. getngmin(dirname,floor)
  3226. char *dirname;
  3227. ART_NUM floor;
  3228. X{
  3229. X    register DIR *dirp;
  3230. X    register struct DIRTYPE *dp;
  3231. X    register ART_NUM min = 1000000;
  3232. X    register ART_NUM maybe;
  3233. X    register char *p;
  3234. X#ifdef notdef
  3235. X    char tmpbuf[128];
  3236. X#endif
  3237. X    
  3238. X    dirp = opendir(dirname);
  3239. X    if (!dirp)
  3240. X    return 0;
  3241. X    while ((dp = readdir(dirp)) != Null(struct DIRTYPE *)) {
  3242. X    if ((maybe = atol(dp->d_name)) < min && maybe > floor) {
  3243. X        for (p = dp->d_name; *p; p++)
  3244. X        if (!isdigit(*p))
  3245. X            goto nope;
  3246. X#ifdef notdef
  3247. X       /* 
  3248. X        * If newsgroup names ever go entirely numeric, then
  3249. X        * this code will have to be reinserted.
  3250. X        * For the time being, we assume that if a numeric name is
  3251. X        * found, it must be an article (and not a directory).
  3252. X        * This will avoid two stat(2) calls for those running
  3253. X        * rn.
  3254. X        */
  3255. X        if (*dirname == '.' && !dirname[1])
  3256. X        stat(dp->d_name, &filestat);
  3257. X        else {
  3258. X        sprintf(tmpbuf,"%s/%s",dirname,dp->d_name);
  3259. X        stat(tmpbuf, &filestat);
  3260. X        }
  3261. X        if (! (filestat.st_mode & S_IFDIR))
  3262. X#endif
  3263. X        min = maybe;
  3264. X    }
  3265. X      nope:
  3266. X    ;
  3267. X    }
  3268. X    closedir(dirp);
  3269. X    return min==1000000 ? 0 : min;
  3270. X}
  3271. X#endif
  3272. END_OF_FILE
  3273. if test 8738 -ne `wc -c <'ngdata.c'`; then
  3274.     echo shar: \"'ngdata.c'\" unpacked with wrong size!
  3275. fi
  3276. # end of 'ngdata.c'
  3277. fi
  3278. if test -f 'tmpthread.c' -a "${1}" != "-c" ; then 
  3279.   echo shar: Will not clobber existing file \"'tmpthread.c'\"
  3280. else
  3281. echo shar: Extracting \"'tmpthread.c'\" \(6070 characters\)
  3282. sed "s/^X//" >'tmpthread.c' <<'END_OF_FILE'
  3283. X/* $Id: tmpthread.c,v 4.4.3.1 1991/11/22 04:12:21 davison Trn $
  3284. X**
  3285. X** $Log: tmpthread.c,v $
  3286. X** Revision 4.4.3.1  1991/11/22  04:12:21  davison
  3287. X** Trn Release 2.0
  3288. X** 
  3289. X*/
  3290. X
  3291. X/* tmpthread.c -- for creating a temporary discussion-thread file
  3292. X**
  3293. X** Usage:  tmpthread [opts] news.group last# first# addmax# /tmp/filename
  3294. X*/
  3295. X
  3296. X#include "EXTERN.h"
  3297. X#include "common.h"
  3298. X#include "threads.h"
  3299. X#ifdef SERVER
  3300. X#include "server.h"
  3301. X#endif
  3302. X#include "INTERN.h"
  3303. X#define TMPTHREAD
  3304. X#include "mthreads.h"
  3305. X
  3306. X#ifdef TZSET
  3307. X#include <time.h>
  3308. X#else
  3309. X#include <sys/time.h>
  3310. X#include <sys/timeb.h>
  3311. X#endif
  3312. X
  3313. struct stat filestat;
  3314. X
  3315. char buf[LBUFLEN+1];
  3316. char *filename, *group, *tmpname;
  3317. X
  3318. int first, last, max, start;
  3319. int log_verbosity = 0, debug = 0, slow_down = 0;
  3320. int ignore_database = 0, read_from_tmp = 0;
  3321. X
  3322. char nullstr[1] = "";
  3323. X
  3324. X#ifdef XTHREAD
  3325. int size;
  3326. X#else
  3327. XFILE *fp;
  3328. X#endif
  3329. X
  3330. X#ifdef TZSET
  3331. time_t tnow;
  3332. X#else
  3333. struct timeb ftnow;
  3334. X#endif
  3335. X
  3336. X#ifdef SERVER
  3337. char *server;
  3338. X#endif
  3339. X
  3340. SIGRET int_handler();
  3341. X
  3342. int
  3343. main(argc, argv)
  3344. int  argc;
  3345. char *argv[];
  3346. X{
  3347. X    char *cp;
  3348. X
  3349. X    while (--argc) {
  3350. X    if (**++argv == '-') {
  3351. X        while (*++*argv) {
  3352. X        switch (**argv) {
  3353. X        case 'D':
  3354. X            debug++;
  3355. X            break;
  3356. X        case 'i':
  3357. X            ignore_database++;
  3358. X            break;
  3359. X        case 's':
  3360. X            if (*++*argv <= '9' && **argv >= '0') {
  3361. X            slow_down = atoi(*argv);
  3362. X            while (*++*argv <= '9' && **argv >= '0') {
  3363. X                ;
  3364. X            }
  3365. X            } else {
  3366. X            slow_down = 1L * 1000 * 1000;
  3367. X            }
  3368. X            --*argv;
  3369. X            break;
  3370. X        case 't':    /* Use tmpfile w/no byte-order changes */
  3371. X            read_from_tmp = 1;
  3372. X            break;
  3373. X        case 'T':    /* Use tmpfile w/possible byte-order changes */
  3374. X            read_from_tmp = 2;
  3375. X            break;
  3376. X        case 'v':
  3377. X            log_verbosity++;
  3378. X            break;
  3379. X        default:
  3380. X            fprintf(stderr, "Unknown option: '%c'\n", **argv);
  3381. X            exit(1);
  3382. X        }
  3383. X        }
  3384. X    } else {
  3385. X        break;
  3386. X    }
  3387. X    }
  3388. X
  3389. X    if (argc < 5) {
  3390. X      give_usage:
  3391. X    fprintf(stderr,
  3392. X"Usage:  tmpthread [opts] news.group last# first# addmax# /tmp/filename\n");
  3393. X    exit(1);
  3394. X    }
  3395. X
  3396. X    group = argv[0];
  3397. X    last = atoi(argv[1]);
  3398. X    first = atoi(argv[2]);
  3399. X    max = atoi(argv[3]);
  3400. X    tmpname = argv[4];
  3401. X
  3402. X    if (first < 0 || last < first - 1 || max <= 0) {
  3403. X    goto give_usage;
  3404. X    }
  3405. X
  3406. X    /* Initialize umask(), file_exp(), etc. */
  3407. X    mt_init();
  3408. X
  3409. X#ifdef SIGHUP
  3410. X    if (sigset(SIGHUP, SIG_IGN) != SIG_IGN) {
  3411. X    sigset(SIGHUP, int_handler);
  3412. X    }
  3413. X#endif
  3414. X    if (sigset(SIGINT, SIG_IGN) != SIG_IGN) {
  3415. X    sigset(SIGINT, int_handler);
  3416. X    }
  3417. X#ifdef SIGQUIT
  3418. X    if (sigset(SIGQUIT, SIG_IGN) != SIG_IGN) {
  3419. X    sigset(SIGQUIT, int_handler);
  3420. X    }
  3421. X#endif
  3422. X    sigset(SIGTERM, int_handler);
  3423. X#ifdef SIGBUS
  3424. X    sigset(SIGBUS, int_handler);
  3425. X#endif
  3426. X    sigset(SIGSEGV, int_handler);
  3427. X#ifdef SIGTTIN
  3428. X    sigset(SIGTTIN, SIG_IGN);
  3429. X    sigset(SIGTTOU, SIG_IGN);
  3430. X#endif
  3431. X
  3432. X#ifdef lint
  3433. X    int_handler(SIGINT);
  3434. X#endif
  3435. X
  3436. X#ifdef SERVER
  3437. X    if ((server = get_server_name(0)) == NULL) {
  3438. X    log_entry("couldn't find name of news server.\n");
  3439. X    exit(1);
  3440. X    }
  3441. X    switch (server_init(server)) {
  3442. X    case OK_NOPOST:
  3443. X    case OK_CANPOST:
  3444. X    break;
  3445. X    case ERR_ACCESS:
  3446. X    log_entry("Server %s rejected connection.\n", server);
  3447. X    exit(1);
  3448. X    default:
  3449. X    log_entry("Couldn't connect with server %s.\n", server);
  3450. X    exit(1);
  3451. X    }
  3452. X#endif
  3453. X
  3454. X    /* See if this machine needs byte-order translation for the database */
  3455. X    word_same = long_same = TRUE;
  3456. X    if (read_from_tmp != 1) {
  3457. X#ifdef XTHREAD
  3458. X    put_server("XTHREAD DBINIT");
  3459. X    rawcheck_server(buf, sizeof buf);
  3460. X    size = rawget_server((char*)&mt_bmap, sizeof (BMAP));
  3461. X    if (size < sizeof (BMAP) - 1) {
  3462. X#else
  3463. X    if ((fp = fopen(file_exp(DBINIT), FOPEN_RB)) == Nullfp
  3464. X     || fread((char*)&mt_bmap, 1, sizeof (BMAP), fp) < sizeof (BMAP)-1) {
  3465. X#endif
  3466. X        log_entry("db.init read failed -- assuming no byte-order translations.\n\n");
  3467. X        mybytemap(&mt_bmap);
  3468. X    } else {
  3469. X        int i;
  3470. X
  3471. X        if (mt_bmap.version != DB_VERSION) {
  3472. X        log_entry("Thread database is not the right version -- ignoring it.\n");
  3473. X        ignore_database = 1;
  3474. X        }
  3475. X        mybytemap(&my_bmap);
  3476. X        for (i = 0; i < sizeof (LONG); i++) {
  3477. X        if (i < sizeof (WORD)) {
  3478. X            if (my_bmap.w[i] != mt_bmap.w[i]) {
  3479. X            word_same = FALSE;
  3480. X            }
  3481. X        }
  3482. X        if (my_bmap.l[i] != mt_bmap.l[i]) {
  3483. X            long_same = FALSE;
  3484. X        }
  3485. X        }
  3486. X    }
  3487. X#ifdef XTHREAD
  3488. X    while (rawget_server(buf, sizeof buf)) {
  3489. X        ;        /* trash any extraneous bytes */
  3490. X    }
  3491. X#else
  3492. X    if (fp != Nullfp) {
  3493. X        fclose(fp);
  3494. X    }
  3495. X#endif
  3496. X    }
  3497. X
  3498. X    /* What time is it? */
  3499. X#ifdef TZSET
  3500. X    (void) time(&tnow);
  3501. X    (void) tzset();
  3502. X#else
  3503. X    (void) ftime(&ftnow);
  3504. X#endif
  3505. X
  3506. X#ifdef SERVER
  3507. X    sprintf(buf, "GROUP %s", group);
  3508. X    put_server(buf);
  3509. X    if (get_server(buf, sizeof buf) < 0 || *buf != CHAR_OK) {
  3510. X    log_entry("NNTP failure on group `%s'.\n", group);
  3511. X#else
  3512. X    strcpy(cp = buf, group);
  3513. X    while ((cp = index(cp, '.'))) {
  3514. X    *cp = '/';
  3515. X    }
  3516. X    filename = file_exp(buf);        /* relative to spool dir */
  3517. X    if (chdir(filename) < 0) {
  3518. X    if (errno != ENOENT) {
  3519. X        log_entry("Unable to chdir to `%s'.\n", filename);
  3520. X    }
  3521. X#endif
  3522. X    exit(1);
  3523. X    } else {
  3524. X    if (read_from_tmp) {
  3525. X        filename = tmpname;
  3526. X    } else {
  3527. X#ifdef XTHREAD
  3528. X        ignore_database = TRUE;
  3529. X#else
  3530. X        filename = thread_name(group);
  3531. X#endif
  3532. X    }
  3533. X    if (ignore_database || !init_data(filename) || !read_data()) {
  3534. X        (void) init_data(Nullch);
  3535. X        total.last = first - 1;
  3536. X        total.first = first;
  3537. X    }
  3538. X    start = total.last + 1;
  3539. X    if (start < last - max + 1) {
  3540. X        start = last - max + 1;
  3541. X    }
  3542. X    process_articles(first, last);
  3543. X    putchar('\n') FLUSH;
  3544. X    if (!write_data(tmpname)) {
  3545. X        exit(1);
  3546. X    }
  3547. X    }
  3548. X    return 0;
  3549. X}
  3550. X
  3551. SIGRET
  3552. int_handler(sig)
  3553. int sig;
  3554. X{
  3555. X    /* Simply bug out with an error flag. */
  3556. X    printf("interrupt %d!\n", sig) FLUSH;
  3557. X    exit(1);
  3558. X}
  3559. X
  3560. void
  3561. wrap_it_up(ret)
  3562. int ret;
  3563. X{
  3564. X    exit(ret);
  3565. X}
  3566. X
  3567. X/* Generate a "log entry" for the interactive user.
  3568. X*/
  3569. X/*VARARGS1*/
  3570. void
  3571. log_entry(fmt, arg1, arg2)
  3572. char *fmt;
  3573. long arg1;
  3574. long arg2;
  3575. X{
  3576. X    printf("tmpthread: ");
  3577. X    printf(fmt, arg1, arg2);
  3578. X    fflush(stdout);
  3579. X}
  3580. X
  3581. X/* Generate a "log entry", with newsgroup name for the interactive user.
  3582. X*/
  3583. X/*VARARGS1*/
  3584. void
  3585. log_error(fmt, arg1, arg2, arg3)
  3586. char *fmt;
  3587. long arg1;
  3588. long arg2;
  3589. long arg3;
  3590. X{
  3591. X    log_entry("%s: ", group);
  3592. X    printf(fmt, arg1, arg2, arg3);
  3593. X    fflush(stdout);
  3594. X}
  3595. END_OF_FILE
  3596. if test 6070 -ne `wc -c <'tmpthread.c'`; then
  3597.     echo shar: \"'tmpthread.c'\" unpacked with wrong size!
  3598. fi
  3599. # end of 'tmpthread.c'
  3600. fi
  3601. echo shar: End of archive 3 \(of 13\).
  3602. cp /dev/null ark3isdone
  3603. MISSING=""
  3604. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  3605.     if test ! -f ark${I}isdone ; then
  3606.     MISSING="${MISSING} ${I}"
  3607.     fi
  3608. done
  3609. if test "${MISSING}" = "" ; then
  3610.     echo You have unpacked all 13 archives.
  3611.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  3612. else
  3613.     echo You still need to unpack the following archives:
  3614.     echo "        " ${MISSING}
  3615. fi
  3616. ##  End of shell archive.
  3617. exit 0
  3618.